Yank all the matching text first, then do your substitute:

1. Clear a register: `qaq`
1. Set a mark at the original point: `gg/pattern` then `mo`
1. Yank text: `:g//yank A`
1. Substitute: `:%s//replacement/flags`

Now paste: `'o"ap`

The paste will paste all of the matching text at the location of the first match pre-substitution. 

If you want to save each match and the line it came from, I’d write a function to create a buffer-local dictionary (`line -> text` assuming one match per line, or `line -> { column -> text }`—dict of dict—for multiple matches anticipated), loop over the matches, grab the text and line number for the dicts, then do the substitution. Then you could write a separate function to "restore" from this dictionary based on line (and column)