Viviani clocked 5hr 36min 45sec after the mostly flat run through central Italy, edging out Slovak Peter Sagan, riding for Bora-Hansgrohe on the line.
Colombian Fernando Gaviria of the UAE Team Emirates finished third in the same time.
"It was a chaotic sprint," said Viviani who gave his team a second win after France's Julian Alaphilippe on Thursday.
"Even the general classification riders were fighting for position to avoid losing any time.
"I lost my two lead-out guys but we always have a spare one and, this time, it was Zdenek Stybar. He put me on a good wheel and that was Peter Sagan's."
Britain's Adam Yates, of Mitchelton-Scott, holds the leader's blue jersey.
"It's been a long day but the sprinters' teams wanted to control," said Yates.
"We sat behind them and I tried to save energy. Tomorrow is not as hard as stage 5 but it could still be decisive."
Saturday's hilly fourth stage covers 221km from Foligno to Fossombrone.
Results from the third stage of the Tirreno-Adriatico cycling stage race, over 226km from Pomarance to Foligono:
1. Elia Viviani (ITA/DEC) 5hr 26min 46sec (average: 41.6 km/h), 2. Peter Sagan (SVK/BOR) same time, 3. Fernando Gaviria (COL/UAE) s.t., 4. Giacomo Nizzolo (ITA/DDT) s.t., 5. Jens Keukeleire (BEL/LOT) s.t., 6. Davide Cimolai (ITA/ICA) s.t., 7. Clement Venturini (FRA/ALM) s.t., 8. Jasper Stuyven (BEL/TRE) s.t., 9. Davide Ballerini (ITA/AST) s.t., 10. Luca Pacioni (ITA/WIL) s.t.
1. Adam Yates (GBR/Mitchelton) 10hr 37min 19sec, 2. Brent Bookwalter (USA/MIT) same time, 3. Primoz Roglic (SLO/JUM) at 7sec, 4. Laurens De Plus (BEL/JUM) 7, 5. Tom Dumoulin (NED/SUN) 22, 6. Sam Oomen (NED/SUN) 22, 7. Soren Kragh Andersen (DEN/SUN) 22, 8. Julian Alaphilippe (FRA/DEC) 27, 9. Wouter Poels (NED/SKY) 47, 10. Jonathan Castroviejo (ESP/SKY) 47