Leclerc started from pole position and retained his first place in a clean start. But after the first round of pitstops, Piastri overtook the Ferrari driver on lap 20.
The 26-year-old Leclerc stayed close to the McLaren, and got close to overtaking Piastri several times throughout the race, but Piastri defended well and held on to the lead.
“I tried at the start of the race to get in front and once I dropped out of DRS I didn’t have the race,” Piastri told reporters afterwards.
“After we stop I saw we were pretty close again, I felt like we had a little bit of extra grip and I had to go for it because knew that if I didn’t get past at the start of the stint that I was never going to get past.
“I went for a pretty big lunge and managed to pull it off and hang on for dear life for the next 35 laps. The last couple of laps when Leclerc dropped out of DRS were a little bit more relaxing but there’s no such thing as a relaxing lap around here so it was hard work.
“I think that definitely goes down as one of my better races of my career.”
Leclerc had to settle for second after a tight battle with the Red Bull of Sergio Perez and teammate Carlos Sainz in the second last lap.
“On the medium we were very competitive, and the car felt good. Unfortunately for me, we didn’t do any high fuel running in FP1 and FP2,” Leclerc said.
“We went for a set up direction which in the race was a bit more difficult to manage. Especially on the hard tyres I was struggling to keep those rears and at the end I thought in one corner or two I could put it in the wall, it was very close.
“McLaren and Oscar have done an exceptional job and done better than us.”
While Leclerc was lucky to keep hold of second place, Perez was overtaken by Sainz and the two crashed while battling for third. Perez was looking to stand on the podium for the first time since the Chinese GP in April.
Meanwhile, George Russell in the Mercedes benefited from the incident to gain third place.
Three-time defending champion Max Verstappen of Red Bull was fifth after being overtaken by McLaren’s title challenger Lando Norris in the final laps.
Norris had started the race in 15th after a dreadful qualifying session but recovered to finish in fourth thanks to the collision between Perez and Sainz.
Fernando Alonso was sixth for Aston Martin with Williams benefiting from the late crash to see Alex Albon finish seventh with Argentine rookie Franco Colapinto following him home in eighth.
Seven times world champion Lewis Hamilton was ninth for Mercedes, after starting in the pit lane, and British rookie Oliver Bearman collected the final point for Haas as a stand-in for suspended Kevin Magnussen.
Bearman has now scored points for two different teams in his two races after making his race debut with Ferrari as a stand-in for appendicitis-stricken Sainz in March.
Perez tried and failed to pass Leclerc for second place on the penultimate lap and then found himself fourth as Sainz seized the opportunity to go past.
As the Spaniard and Mexican battled for third at turn two, the cars collided and went into the wall.
“What happened there?” exclaimed Sainz, with Perez asking the same thing in more colourful language.