I have been able to leave the DFU boot loader code and return to the user application code by manually setting the address pointer prior to sending the DFU_DNLOAD request with 0 data.
The only downside is that it seems to fail about 1 out of 4 times. The user application uses the USB IP to implement a HID device. When the exit function works properly the device will automatically enumerate with the PC as a HID device and will run the user application. When it fails the PC will not recognize the device at which point a physical reset is required to start the user application.
I think the problem is related to Note 2 on page 22 of AN3156. This note states:
When performing a jump from the bootloader to a loaded application code which uses the USB IP, the user application has to disable all pending USB interrupts and reset the core before enabling interrupts. Otherwise, a pending interrupt (issued from the boot loader code) may interfere with the user code and cause a functional failure. This procedure is not needed after exiting the system memory boot mode.
Here is the code snippet of the DLL function that performs the exit operation: