I actually got it to work correctly.
I had to switch the first parameter of the method:
apiRetStatus = CyFx3BootUsbStart (CyTrue, myUsbEventCallback);
apiRetStatus = CyFx3BootUsbStart (CyFalse, myUsbEventCallback);
And now it appears to boot the primary FW correctly.
Why is this not set to CyFalse by default?
The first parameter of the CyFx3BootUsbStart () API is a check for re-enumeration and is to set to CyTrue since there is no need for the device to re-enumerate even after loading the new firmware.
In general, the VID and PID of the "boot_fw" and the main firmware are to be kept the same and in this case, even after loading the new firmware, there won't be a need for re-enumeration.
But since you modified the VID and PID, there is a need for the USB block to re-enumerate for the device to come up with the new device VID and PID and to get recognized in the host.
You can keep the VID and PID of the "boot_fw" with your main firmware VID and PID and try using the 'noreenum' parameter set to CyTrue.