To add to this, I tried building up the full clientId and using FacesContext.getCurrentInstance().addMessage(clientId, facesMessage), but when I do that I get no messages at all (perhaps it's checking for the matching component and ignoring if it cannot find it).
Perhaps there is no way of adding messages to individual fields as part of a pageflow transition. If so we will have to abandon using pageflow, which would be a shame.
An update on this.
I found that adding messages directly to the FacesContext does work, but only if I remove the redirect from the page the error occurred on.
This isn't ideal, but it was enough to keep me using Pageflow.