diff --git a/src/dehacked.c b/src/dehacked.c
index 52b1623d281a0eff9c79160b539e6d61ffc098ad..f30ec58e7298e3f7ee7981a928ae871f4216a371 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -1151,6 +1151,9 @@ static void readlevelheader(MYFILE *f, INT32 num)
 #endif
 			else if (fastcmp(word, "MUSICTRACK"))
 				mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
+			else if (fastcmp(word, "MUSICPOSTBOSS"))
+				deh_strlcpy(mapheaderinfo[num-1]->muspostbossname, word2,
+					sizeof(mapheaderinfo[num-1]->muspostbossname), va("Level header %d: post-boss music", num));
 			else if (fastcmp(word, "FORCECHARACTER"))
 			{
 				strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
diff --git a/src/doomstat.h b/src/doomstat.h
index 092fce41814e2985c7aa55702a37c72cee7609b8..38be6968c104036121d1474107945f4e7eb91f77 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -256,6 +256,9 @@ typedef struct
 	UINT8 numGradedMares;   ///< Internal. For grade support.
 	nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
 
+	// Music stuff.
+	char muspostbossname[7]; ///< Post-bossdeath music.
+
 	// Lua stuff.
 	// (This is not ifdeffed so the map header structure can stay identical, just in case.)
 	UINT8 numCustomOptions;     ///< Internal. For Lua custom value support.
diff --git a/src/lua_maplib.c b/src/lua_maplib.c
index b929fc0bc643c6ac72c581baf79eff67b0428b27..d4bea333e362c6a1ffcb154d10a787b731f8171c 100644
--- a/src/lua_maplib.c
+++ b/src/lua_maplib.c
@@ -1760,6 +1760,8 @@ static int mapheaderinfo_get(lua_State *L)
 		lua_pushstring(L, header->musname);
 	else if (fastcmp(field,"mustrack"))
 		lua_pushinteger(L, header->mustrack);
+	else if (fastcmp(field,"muspostbossname"))
+		lua_pushstring(L, header->muspostbossname);
 	else if (fastcmp(field,"forcecharacter"))
 		lua_pushstring(L, header->forcecharacter);
 	else if (fastcmp(field,"weather"))
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 9235a1d0f134bbc42a65e061c30a9380ba97a093..83b50a0ccae20fbb176e8cb1b86c8d10f4bbe00d 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -3529,6 +3529,17 @@ void A_BossDeath(mobj_t *mo)
 		EV_DoElevator(&junk, elevateUp, false);
 		junk.tag = 682;
 		EV_DoElevator(&junk, elevateHighest, false);
+
+		// change the music if specified
+		if (mapheaderinfo[gamemap-1]->muspostbossname && !strncmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
+		{
+			// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
+			// So just park ourselves in the mapmus variables.
+			strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
+			mapmusname[6] = 0;
+			mapmusflags = MUSIC_RELOADRESET;
+			S_ChangeMusicAdvanced(mapmusname, mapmusflags, true, 0, (1*MUSICRATE)+(MUSICRATE/2), 0);
+		}
 	}
 
 bossjustdie:
@@ -11636,4 +11647,4 @@ void A_CheckFlags2(mobj_t *actor)
 
 	if (actor->flags2 & locvar1)
 		P_SetMobjState(actor, (statenum_t)locvar2);
-}
\ No newline at end of file
+}
diff --git a/src/p_setup.c b/src/p_setup.c
index c62f281b3ee461eed4ccce49121c6a23d988bbb8..f451401ae27e16f9f29e1330bd7215df562db9f8 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -208,6 +208,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
 	snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
 	mapheaderinfo[num]->musname[6] = 0;
 	mapheaderinfo[num]->mustrack = 0;
+	mapheaderinfo[num]->muspostbossname[6] = 0;
 	mapheaderinfo[num]->forcecharacter[0] = '\0';
 	mapheaderinfo[num]->weather = 0;
 	mapheaderinfo[num]->skynum = 1;