This is a recurring issue, which usually is solvable by selecting a raw driver, but I can't seem to get it to work with CUPS in CentOS 7...
The objective is simply to send a PCL file to a Linux/CUPS printer, as is. This is the way we did things back in the AMOS days, and many are content to continue creating their own PCL. But in the CUPS world, they want to run files through all kinds of filtering, first identifying the type of file using a bunch of rules encoded in the mime.types file, then converting it to Postscript, then passing through a driver for the printer, etc. The result is often some change to the file which causes the PCL to go haywire.
In theory, passing the "-o raw" switch on the lpr command line should bypass all of that, but I'm still getting the messed up output.
I even created a pseudo-network printer that simply captured the output and wrote it to a file, and the resulting file has the same hash as the original, which would appear to prove that there was no filtering, but I can't explain why the printed result (outputting to socket//x.x.x.x:9100) is corrupted.
In past versions of Linux, using -o raw or selecting the "generic raw queue" printer model has always worked, but something seems to have changed in CentOS 7/CUPS 1.6.3.22.
If anyone else has run into this, or found a solution, I'd love to hear about it.
The one solution I've come up with for the moment is to print through ATE instead. I replace the device in the printer init file with AUXLOC:printer and set the ATE printer configuration in the Connection Properties to passthrough, in which case it prints fine.