I think we need to mention some of the basics of writing to FLASH.
The erased state of a FLASH cell is "1" (not "0"), so an erased word in code memory is 0x3FFF (14 bits).
Individual bits can be written from "1" to "0" as required, so 0x3FFF can be overwritten as any 14 bit value, but you can NOT write a "0" bit back to "1". The only way to get the bits back to "1" is to erase the FLASH, which erases an entire "row", which in your PIC is 32 words. (See section "11.3 Flash Program Memory Overview" in your datasheet).
So, you can't just declare a variable as "const" and allow the compiler to place it in the middle of your code memory, as erasing that row will also erase other variables or part of your code!
That's why I said it's better to reserve a block of FLASH t the top for data storage, and tell the compiler not to use it.
For more details, see: https://microchipdeveloper.com/tip:22
Another complication is, when XC8 stores variables in code memory, it only uses the lower 8 bits of each 14 bit word.
So, an "int" variable (16 bits) is spread over two words.
If you do need a 16 bit variable, you can do the same, spreading it over two words.
You can tell XC8 to read it like a standard variable, by stating its address using "@" in C90 mode, or "__at" in C99 mode. Alternatively, you can just use a PM read routine to read it directly using the PM registers.
Have a read of the above, then come back with any details that are still unclear.