AVR self-programming
well... you can always execute a software initiated reset ala exploitation of the watchdog timer... and put data in eeprom to communicate to your bootloader code as to what you wanted it to do...
http://www.cs.mun.ca/~paul/cs4723/material/atmel/avr-libc-user-manual-1.6.5/FAQ.html#faq_softreset
Looking at page 272 of the ATMega168 manual (section 6: Entering the Boot Loader Program), the first line states:
Entering the Boot Loader takes place by a jump or call from the application program. This may be initiated by a trigger such as a command received via USART, or SPI interface.
So it would seem to me that definitively you can and must be able to call the bootloader functions from application code. As long as you are executing code that resides in the Boot Loader section of memory, SPM instructions can be executed, and therefore you should be able to self-program any time your application program jumps into the boot loader code.
You can just jump to the bootloader block and everything should be fine. (just remember to move the interrupt vectors as well)