I've discovered that using a plupload element in a form that submits via AJAX "should" break.
During form building, core's form_builder() will assign a generated #id using drupal_html_id(), if #id is not already set on the element. When the form is submitted, the values in $_POST have keys containing #id. So plupload_element_value() grabs $element['#id'] to find which POSTed values to process. This function is running after the form has been rebuilt, though, meaning drupal_html_id() has regenerated that #id. The problem is, upon an AJAX POST, drupal_html_id() avoids duplicating IDs on the page by incrementing them. The preg_match() therefore fails and an empty $files array is returned, leaving form API submit handlers with nothing to process.
The fix is simple: strip possible incrementation off the end of the ID before putting it into the regex - change plupload.module, line 104:
$id = preg_replace('/--[0-9]+/', '', $element['#id'], 1);
Note: Interestingly, this problem was cropping up only in IE. I think it's because in IE, inspection showed that $_POST['ajax_html_ids'] was an array - as one would expect, for it to work properly in drupal_html_id(). However in Firefox, $_POST['ajax_html_ids'] was a comma-delimited string. And thus, the incrementation didn't happen, the $regex using $element['#id'] worked, and all was well.