Xherdan Shaqiri opened the scoring in a fiery end-to-end first half before Aleksandar Mitrovic levelled six minutes later.
Dusan Vlahovic handed Serbia their first lead after 35 minutes but saw it cancelled out by Breel Embolo who sent the sides level into the break.
It took Remo Freuler just three minutes to net the eventual winner after the restart and - despite chances for both sides - ensured Switzerland sealed second spot in Group G.
Switzerland edged the 2018 group-stage encounter between the two sides when Granit Xhaka cancelled out Mitrovic's opener and Shaqiri fired in a last-gasp winner.
Both men were back in Murat Yakin's starting XI for Switzerland, who got off to an electric start with two good attempts inside the first 25 seconds, Vanja Milinkovic-Savic saving a close-range effort from Embolo before Xhaka failed to bury the rebound.
Serbia won the first corner but Nikola Milenkovic nodded off target. Soon after, Dusan Tadic found Andrija Zivkovic in space who tried to pull his side ahead after 10 minutes but his powerful strike from distance instead thumped off the left post and at the feet of Mitrovic, who saw his attempt gathered by Gregor Kobel.
It took 90 minutes for Shaqiri to find the back of the next in 2018 - this time it took just 20, beginning with Ricardo Rodriguez's drive into the area from the left.
Strahinja Pavlovic was there to block the swerving cross but failed to clear, instead directing the ball to Djibril Sow. The Eintracht Frankfurt midfielder teed up Shaqiri, who sent a left-footed strike into the bottom-right corner.
It took just six minutes for Serbia to respond. Tadic floated in a cross from outside the area, perfectly timing it to meet Mitrovic and the Fulham striker, on the run, drew things level with a fine header into the top corner.
Shaqiri nearly pulled Switzerland ahead but it was Serbia who took the lead when Freuler gave away the ball near the penalty spot and Vlahovic pounced, firing past the far post with a leaping left-footed strike.
It was all square by the break, however, when Silvan Widmer sent a low cross across the face of goal for a sliding Embolo to finish from inside the six-yard box.
Switzerland restored the lead inside three second-half minutes. A patient passing sequence ended in a brilliant move by Ruben Vargas, who issued a perfect backheel for Freuler, who sent a powerful strike into the bottom corner.
Serbia were spared falling further behind by the offside flag but missed a good chance to level when Kobel did well to read Filip Kostic's attempt from the left.
Tensions rose after Mitrovic appealed for a penalty after claiming he had been pulled down by Fabian Schar. The referee did not agree, his decision provoking substitutes to spill onto the pitch for a brief tussle.
Several would come on in hopes of shifting momentum, but with the end in sight, the Swiss soon shifted to shut-down mode, surviving seven minutes of stoppage time - including another heated disagreement between the two sides - to book their trip to the knockout rounds.