The Briton emerged victorious on stage seven's closing bunch sprint in Fougeres in northwestern France, edging out green jersey holder Andre Greipel (Lotto Soudal) in second and Peter Sagan (Tinkoff-Saxo) in third.
Cavendish had narrowly lost out to Greipel in Amiens on Wednesday, but was able to have the final say on this occasion.
Chris Froome (Sky) regained the maillot jaune he took ownership of on Thursday following Tony Martin's decision to abandon the race due to his crash on stage 6.
Sagan moved into second place overall with the time bonus he gained for his third place finish.
He lies 11 seconds behind Froome, with Tejay van Garderen (BMC) a further two seconds adrift in third.
The day was mostly uneventful prior to the finish, with no coastal roads, cobbles or steep climbs to negotiate.
The day's breakaway on the 190.5km route included Anthony Delaplace and Brice Feillu (Bretagne-Séché Environnement), Daniel Teklehaimanot (MTN-Qhubeka), Luis Angel Maté (Cofidis), and Kristjan Durasek (Lampre-Merida).
Their gap at the front had been cut to under a minute with 60km to go before it grew larger again when the leaders upped the pace.
Inside of 15km to go, however, they were finally caught, with FJD active at the front of the peleton before Lotto-Soudal took over.
Katusha lined up three riders for Alexander Kristoff in the final half-kilometre and Greipel soon followed, but Cavendish was ready for them, accelerating from behind Sagan at the perfect time and winning by half a bike length.
Stage 7 results:
1 Mark Cavendish (GBr) Etixx – Quick-Step 4:27:25
2 Andre Greipel (Ger) Lotto Soudal
3 Peter Sagan (Svk) Tinkoff-Saxo
4 John Degenkolb (Ger) Team Giant-Alpecin
5 Alexander Kristoff (Nor) Team Katusha
6 Arnaud Demare (Fra) FDJ.fr
7 Tyler Farrar (USA) MTN – Qhubeka
8 Reinardt Janse Van Rensburg (RSA) MTN – Qhubeka
9 Davide Cimolai (Ita) Lampre-Merida
10 Sam Bennett (Irl) Bora-Argon 18
General classification after Stage 7:
1 Christopher Froome (GBr) Team Sky 26:40:51
2 Peter Sagan (Svk) Tinkoff-Saxo 0:00:11
3 Tejay Van Garderen (USA) BMC Racing Team 0:00:13
4 Tony Gallopin (Fra) Lotto Soudal 0:00:26
5 Greg Van Avermaet (Bel) BMC Racing Team 0:00:28
6 Rigoberto Uran (Col) Etixx – Quick-Step 0:00:34
7 Alberto Contador (Spa) Tinkoff-Saxo 0:00:36
8 Zdenek Stybar (Cze) Etixx – Quick-Step 0:00:52
9 Geraint Thomas (GBr) Team Sky 0:01:03
10 Warren Barguil (Fra) Team Giant-Alpecin 0:01:07