Marcin Gortat added 16 points to help the Suns win their second straight game and improve to 8-2 since the All-Star break.
Rodney Stuckey scored 23 points to lead the Pistons, who lost for the second time in their last six games.
Phoenix trailed 80-79 to start the fourth quarter before Robin Lopez made a pair of free throws and dropped in a hook from the left base line to give the Suns an 83-80 lead. The lead changed hands five times in the fourth, but the Suns held Detroit to two points in the final 1:41 to hold on.
After the Pistons tied the game at 95, Dudley scored on a putback and Frye buried a 3-pointer to give Phoenix a 100-97 lead.
Stuckey scored 17 of his points in the opening half and Brandon Knight added 14 to help Detroit take a 59-54 lead at the break.
The Suns took a 17-11 lead midway through the opening period before the Pistons broke off a 13-3 run in the second. Stuckey hit two free throws with just over 7 minutes remaining before intermission to give Detroit its first lead, 40-38.
Dudley converted a three-point play to tie it at 46 with just under 5 minutes left in the half, but the Pistons held the lead the rest of the way. Jonas Kerebko and Knight each hit a 3-pointer in closing minutes of the second quarter to keep Detroit ahead.
The Suns came out stronger in the second half. After Grant Hill hit two jumpers and buried a 3-pointer with 4 minutes left in the third period, the Suns tied it at 70.
NOTES: After missing the last game, Hill and Steve Nash returned the Phoenix lineup. ... The Suns won a season-high three straight for the second time this season.