Cahill (5-5) won his third straight start, striking out eight and walking two.
He outdueled Dan Haren, who limited the Diamondbacks to a single run through five innings before surrendering four more in the sixth.
Aaron Hill hit a three-run homer off Haren (4-7) during Arizona's big inning. Arizona has won two in a row and seven of its last nine to reach .500.
Brad Ziegler needed only five pitches to retire the Angels in the eighth and David Hernandez completed the shutout in a non-save situation.