Pep Guardiola’s side slipped to only their second Premier League defeat of the season on the Spaniard’s 200th game in charge at the club.
City remain third in the league table while Palace move up to 13th position.
The visitors took a shock lead after early on when Gallagher dispossessed Laporte to play in Zaha to score his 50th Premier League goal for Palace.
Following the opener, Palace defended well and City failed to create many clear-cut chances throughout the first half.
Just before the break, the hosts were reduced to 10 men after Laporte brought down Zaha and was shown a straight red card for denying a clear goalscoring opportunity.
Palace should have doubled their lead five minutes into the second half but Marc Guehi failed to hit the target with a close-range header.
Within the space of two minutes, both sides had goals ruled out for offside. Zaha thought he scored his second of the day but his strike was disallowed.
With two minutes remaining, Gallagher sealed an impressive win for Palace with a curling finish past City goalkeeper Ederson