Chelsea took the lead after 36 minutes following a mix-up between Benjamin Mendy and Ilkay Gundogan, allowing Christian Pulisic to advance from inside his own half and slot past Ederson.
Kevin De Bruyne made it 1-1 on 55 minutes with a spectacular free-kick, taking him to 10 goals in a Premier League season for the first time.
Raheem Sterling hit a post moments later before Kyle Walker cleared superbly off the line to deny Pulisic a second.
The decisive moment came when Fernandinho was shown a red card following a Video Assistant Referee review for a deliberate handball to deny Chelsea substitute Tammy Abraham on the goalline.
Willian fired in the resulting penalty to put Chelsea back in front with 12 minutes remaining.
City were unable to respond, leaving them 23 points behind champions Liverpool with seven matches left to play.
Chelsea stay fourth with 54 points.
Chelsea: 1 Jul v West Ham (A)
Man City: 2 Jul v Liverpool (H)