Thomas attacked with just under five kilometres to go in the mammoth 229km stage, initially being joined by Bob Jungels (Quick-Step Floors), Jonathan Castroviejo (Movistar) and race leader Damiano Caruso (BMC Racing).
With the Team Sky rider setting a fast pace on the front, the other three riders argued over who should take Thomas’ wheel, allowing the Welshman to glide off the front with a decent gap over the chasing bunch.
After such a long stage Thomas looked remarkably fresh, remaining still on his bike as he held a 17 second lead into the final kilometre.
Tom Dumoulin (Team Sunweb) launched a counter-attack from the peloton, but it was too little too late, with Thomas holding on to win by nine seconds.
Greg Van Avermaet (BMC Racing) crossed the line in fourth place, which was enough to see the defending champion take the overall lead off team-mate Caruso.
How it happened
Stage four of Tirreno-Adriatico saw the peloton head south from the town of Camaoire that hosted yesterday’s team time trial, with the first half of the 229km-long stage going down the Tyrrhenian coast, before cutting inland towards a lumpy hilly circuit around the town of Pomarance.
A five-man group escaped almost from the gun, consisting of Hugo Houle (Ag2r La Mondiale), Davide Ballerini and Raffaello Bonusi (Androni Giocattoli), Mirco Maestri (Bardiani CSF), Alan Marangoni (Nippo-Vini Fantini), and Charles Planet (Team Novo Nordisk), who quickly built an advantage of nearly six minutes.
Having won the team time trial, BMC Racing were a constant presence on the front of the bunch, as they kept best young rider Stefan Küng and overall leader Damiano Caruso out of trouble and steadily pulled the breakaway back as the first of the three categorised climbs began.
Despite hard work from the break, their advantage steadily fell, and they were eventually caught with 27km as the race hit its final climb.
BMC Racing continued to set a hard tempo on the climb, but allowed two men to slip off the front in form of Hideto Nakane (Nippo-Vini Fantini) and a battered and bruised Gianni Moscon (Team Sky).
Over the final 10km the road rose steadily to the line, meaning a battle for position with none of the overall contenders wanting to be caught out.
Quick-Step set a fast pace, and it was Bob Jungels who attacked with 5.5km to go, quickly followed by Geraint Thomas, Tim Wellens (Lotto-Soudal), and Damiano Caruso, before the rest of the group caught up as Jungels eased up.
After a brief pause, Thomas launched the next move, this time with Jungels tucked in his wheel along with Caruso and Jonathan Castroviejo.
Thomas set the pace, and the other three riders in the break prevaricated as to who should follow the Welshman, allowing the Team Sky rider to go solo.
In no time Thomas had opened a significant gap, and as Caruso, Castroviejo and Jungels were caught, Thomas held an advantage of 17 seconds into the final kilometre.
A late attack from Tom Dumoulin was enough to pull himself clear of the chasing pack for second place, but Thomas was not to be caught, taking his first victory of the season.
Dumoulin was followed across the line by Peter Sagan (Bora-Hansgrohe) and Greg Van Avermaet (BMC Racing), with Van Avermaet’s placing enough to put him into the leader’s blue jersey.
Tirreno-Adriatico continues on Friday with a 204km-long stage to Montalto di Castro, before the queen stage of the race on Saturday
Tirreno-Adriatico 2017, stage two: Camaiore to Pomerance (228km)
1. Geraint Thomas (GBr) Team Sky, in 5-51-44
2. Tom Dumoulin (Ned) Team Sunweb, at 9 secs
3. Peter Sagan (Svk) Bora-Hansgrohe
4. Greg Van Avermaet (Bel) BMC Racing
5. Francesco Gavazzi (Ita) Androni Giocattoli
6. Michal Kwiatkowski (Pol) Team Sky
7. Adam Yates (GBr) Orica-Scott
8. Rohan Dennis (Aus) BMC Racing
9. Nairo Quintana (Col) Movistar
10. Simon Clarke (Aus) Cannondale-Drapac, all at same time
General classification after stage two
1. Greg Van Avermaet (Bel) BMC Racing, in 6-15-14
2. Rohan Dennis (Aus) BMC Racing
3. Tejay Van Garderen (USA) BMC Racing
4. Damiano Caruso (Ita) BMC racing, all at same time
5. Niki Terpstra (Ned) Quick-Step Floors, at 16 secs
6. Bob Jungels (Lux) Quick-Step Floors, at same time
7. Nairo Quintana (Col) Movistar, at 21 secs
8. Moreno Moser (Ita) Astana
9. Sebastien Reichenbach (Sui) FDJ
10. Jonathan Castroviejo (Esp) Movistar, all at same time