Xherdan Shaqiri’s deflected strike put the Swiss ahead but Aleksandar Mitrovic’s fine header brought Serbia level at Stadium 974.
Dusan Vlahovic then gave Serbia the lead only for Breel Embolo to equalise before half-time.
Remo Freuler’s brilliant goal early in the second half sent the Swiss through to the knockout rounds for the fourth time in five World Cups.
Bad blood marred the meeting between the teams at the 2018 tournament, when Granit Xhaka and Shaqiri celebrated goals by making pro-Kosovo gestures that enraged the Serbs.
Tempers flared in the second half on Friday after Serbia appealed for a penalty, with the stadium announcer calling for an end to “all discriminatory chants and gestures” around 15 minutes later.
Switzerland, who had their destiny in their own hands, nearly struck inside 30 seconds but Embolo’s attempt was well blocked by Vanja Milinkovic-Savic, who palmed away the follow-up from Xhaka.
Serbia’s Andrija Zivkovic rattled the post from distance with a sweet curling effort and Vlahovic bundled the rebound straight into goalkeeper Gregor Kobel’s arms.
– Shaqiri strikes –
Shaqiri missed Switzerland’s 1-0 loss to Brazil but returned with a bang as he fired his side in front on 20 minutes.
Ricardo Rodriguez speared a cross into the box which was cleared straight to Djibril Sow, who laid off for Shaqiri to sweep home via the leg of Strahinja Pavlovic in front of the Serbia fans.
This time there was no double eagle gesture. Instead, Shaqiri put his finger to his lips and pointed to the name on his shirt as a handful of bottles rained down.
Serbia hit back within minutes as Switzerland lost the ball in midfield, Dusan Tadic bending in a cross for Mitrovic to meet superbly and nod into the far corner.
Shaqiri steered wide under pressure from Pavlovic after timing his run perfectly to meet Rodriguez’s raking diagonal pass, but the Swiss then paid for another lapse in concentration.
They again ceded possession and Freuler watched on in dismay as his attempted interception served only to tee up Vlahovic to roll the ball beyond Kobel.
But Switzerland equalised a minute before the break as Sow picked out Silvan Widmer in acres of space on the right and his driven low cross was turned in by Embolo.
The Cameroon-born striker’s pressure on a lumbering Pavlovic gave Switzerland their third goal right after half-time, a brilliant team effort finished by Freuler.
Shaqiri clipped in a delicate ball after Embolo won it back high up, and Ruben Vargas’s cushioned backheel left Freuler to guide in from around the penalty spot.
Serbia appealed in vain for a penalty when Mitrovic theatrically fell to the ground, sparking an ugly flashpoint that led to reserve Serbia goalkeeper Predrag Rajkovic being booked.
Substitute Christian Fassnacht spurned a late chance to ease Swiss nerves when clean through on goal.
An unseemly spat between Xhaka and Nikola Milenkovic threatened to boil over, but in the end the Swiss got over the line to set up a date with Cristiano Ronaldo and Portugal.
© Agence France-Presse