Bernardo Silva gave the champions the lead for the first time 14 minutes from the end after latching onto a superb pass from Julian Alvarez, before Erling Haaland completed the job with a well-taken finish as West Ham pressed for an equaliser.
Earlier James Ward-Prowse had given David Moyes’ side a first-half lead that had them on course to overtake City at the top of the table, heading home from Vladimir Coufal’s cross for his second goal since joining in the summer.
Jeremy Doku, making just his second start, levelled with an expertly taken individual effort seconds after half-time, as City took charge of a difficult situation to send the hosts to their first defeat of the season and maintain their own perfect start.
West Ham survived a scare after just seven minutes and they had the heroics of Tomas Soucek and Alphonse Areola to thank. First, Rodri found space from a corner and thumped a far-post header at goal that the goalkeeper did well to push away.
The ball dropped to Haaland whose shot was blocked on the line by Soucek, sticking out his chest and bouncing it clear with his shoulder, before finally Reuben Dias’s effort was tipped over brilliantly by the goalkeeper.
City had West Ham largely penned inside their own half, probing but failing to find the critical pass. Haaland hooked an effort wide after finding room to get on the end of Josko Gvardiol’s cross, then Rodri looked to do it all himself when he carried the ball to the edge of the box and curled a right-footed effort, but his shot arched tamely and was easily gathered by Areola.
The hosts took more of a grip as the half wore on, and when their chance came it was ruthlessly taken.
The ball was given away wide on City’s left by Doku and West Ham broke down the flank with speed and purpose. Coufal was given space to dash into, and as his out-swinging cross arrived into the box there was Ward-Prowse stooping low to guide his header into the corner beyond Ederson.
City’s response was swift and should have yielded an instant equaliser. Doku, looking to make amends, cut inside Coufal on the left and crossed along the ground for Haaland who failed to make good enough contact to sneak it past Aguerd who shovelled it off the goal line. Phil Foden struck left-footed from range but was denied by a crowd of claret and blue shirts as West Ham saw the half out.
It took the champions just 40 seconds to level after the break. Doku received it wide near the left touchline and looked up to find little on inside the box.
Instead he drove Coufal backwards into the area, standing him up and slipping inside with a deft right-foot touch before rolling it inside Areola’s far post in one cleverly executed motion.
City were buoyed. Alvarez hit the post from a free-kick, then Haaland volleyed left-footed from 10 yards after being teed up Rodri’s exquisite chipped pass, a strong right hand thrust into the air from Areola denying them the lead.
Then came West Ham’s turn to go within a whisker, Michail Antonio bursting beyond Dias in a foot race from Lucas Paqueta’s probing ball but taking a fractionally heavy touch at the crucial moment to allow Ederson to smother.
Suddenly the hosts were on top. Emerson spotted a gap in the heart of City’s defence to run into, his effort deflecting narrowly wide, and from the resulting corner Kurt Zouma’s thumping header required a sensational diving save from Ederson.
With 15 minutes to go, City led for the first time and it was the vision and touch of Alvarez that made it. He received the ball near the edge of the box from Silva, who dashed forward and was brilliantly picked out by Alvarez’s chip. Aguerd was inches from intercepting with his head, but it landed back with Silva who dinked it into the corner beyond Areola.
Haaland was denied at close range when getting on the end of Kyle Walker’s cross, West Ham’s goalkeeper adding to a string of impressive saves.
But the Norwegian would not be denied. In the final minutes as West Ham pushed forward, Silva broke with the ball and rolled it across for Haaland to sweep coolly home and cap a fine win.