The Oilers nearly tied it with five minutes left in the first when Perron made a nice pass to a hard-charging Ryan Smyth, but Hiller quickly came across and made the save.
The Oilers did get even six minutes into the second period with a power-play goal when Hall banked a puck in off Hiller with a shot from the side of the net for his 27th of the season.
Perron kept pace with Hall for the team's goal-scoring lead three minutes later while Edmonton was short-handed. He beat Hiller with an off-balance shot from the right circle for his 27th. It was Edmonton's fourth short-handed goal of the season.
The Oilers took a 3-1 lead with just over three minutes left in the second period when Eberle swung a puck out front, and the rebound remained loose in the crease before a pinching Schultz tapped it in.
The Ducks got back within a goal during a power play just 25 seconds into the third period when Perry tipped a Ryan Getzlaf's long wrist shot from the point past Fasth for his 42nd goal.
Edmonton withstood a ton of pressure before getting an insurance goal. Eberle also scored his team-leading 27th with an empty-net goal.
Fasth made 34 saves to earn his first win against his former team.
"The guys played great in front of me," Fasth said. "They cleared a lot of rebounds and blocked a lot of shots. It was a great team effort.
"Of course it is special to play against them and get the win. I have a lot of friends on that team and played for them for a year."
NOTES: It was the fifth and final meeting between the Oilers and Ducks this season. Anaheim went 3-1-1 in the series. The Ducks had won 12 of the past 15 games in Edmonton. ... The Ducks allowed six first-period goals in their three games heading into Edmonton. ... With the playoffs looming, Anaheim rested its two oldest players, Teemu Selanne and Saku Koivu. The Ducks were also without G Frederik Andersen (upper body) and D Cam Fowler (knee). ... LW Jesse Joensuu (ankle), LW Ryan Jones (knee), RW Tyler Pitlick (knee), LW Luke Gazdic (shoulder), RW Nail Yakupov (ankle) and D Andrew Ference (chest) sat out for Edmonton.