The Australian rider remained ensconced towards the front of a diminishing bunch during a messy uphill final kilometre, biding his time to jump clear with 150m to go.
Sagan and Degenkolb were locked in behind Matthews, but were unable to come around him as they knocked shoulders behind.
The victory was also enough for Matthews to move himself into the yellow jersey as erstwhile leader Stefan Küng (BMC Racing) was dropped in the final kilometres.
How it happened
The two breakaway riders of Lasse Norman Hansen (Aqua Blue Sport) and Elmar Reinders (Roompot-Nederlanse Loterij) escaped from the gun at the start of the 159.3km stage from Menziken to the Swiss capital of Bern.
That duo quickly built a substantial lead of more than eight minutes over a relaxed peloton that seemed content to let them enjoy a substantial lead.
Going into the final 60km at the gap was down to less than five minutes and falling steadily, but the chase stalled as Astana leader Miguel Angel Lopez crashed.
The peloton seemed to ease up a little to allow Lopez to regain contact with a number of riders also taking the opportunity for a natural break, allowing a number of kilometres to pass without the gap being reduced.
Hansen clearly saw an opportunity here, and with 45km to go really started to apply the pressure at the front of the race, ramping up the pace and eventually dropping Reinders with 25km to go.
However there were fresh legs in the bunch, and Trek-Segafredo worked hard to pull Hansen back, leaving him with a lead of just 1-30 going on to the final classified climbs with 15km remaining.
Any chance of Hansen surviving to the finish were scuppered on the climb, as he saw his entire advantage disappear on the short, steep ascent of Gümligen, setting the race up for a bunch sprint in Bern.
Trek-Segafredo continued to control the bunch as they went into the final 10km, trying to set John Degenkolb up for victory, but the American team came under increasing pressure from Bora-Hansgrohe, Katusha-Alpecin, and BMC Racing, all eager to look after their sprinters and GC hopefuls.
Trek were back on the front as they went under the flamme rouge, setting a high pace as the road climbed towards the line. However that wasn’t enough to deter Domenico Pozzovivo (Ag2r La Mondiale) from going on the attack with 800m remaining.
Unfortunately for the Italian his move was quickly shut down, and as the road flattened out in the final 500m, a sprint between Matthews, Sagan, and Degenkolb looked inevitable.
Most would have tipped either Sagan and Degenkolb to succeed, but instead Matthews beat them to the punch, launching a perfectly timed sprint to win the stage and move into the race lead.
Tour de Suisse 2017, stage three: Menziken to Bern (159km)
1. Michael Matthews (Aus) Team Sunweb, in 3-49-48
2. Peter Sagan (Svk) Bora-Hansgrohe
3. John Degenkolb (Ger) Trek-Segafredo
4. Tim Wellens (Bel) Lotto Soudal
5. Michael Albasini (Sui) Orica-Scott
6. Patrick Bevin (NZl) Cannondale-Drapac
7. Arthur Vichot (Fra) FDJ
8. Matteo Trentin (Ita) Quick-Step Floors
9. Jan Bakelants (Bel) Ag2r La Mondiale
10. Damiano Caruso (Ita) BMC Racing, all at same time
General classification after stage three
1. Michael Matthews (Aus) Team Sunweb, in 8-18-47
2. Tom Dumoulin (Ned) Team Sunweb, at 10 secs
3. Peter Sagan (Svk) Bora-Hansgrohe, at 11 secs
4. Damiano Caruso (Ita) BMC Racing Team, at 19 secs
5. Michael Albasini (Swi) Orica-Scott, at 20 secs
6. Patrick Bevin (NZl) Cannondale-Drapac, at 22 secs
7. Matteo Trentin (Ita) Quick-Step Floors, at 23 secs
8. John Degenkolb (Ger) Trek-Segafredo, at 24 secs
9. Jon Izaguirre (Spa) Bahrain-Merida, at 25 secs
10. Marc Soler (Esp) Movistar, at same time