Pass PIL image to texture.ImageBuff()
You can it like this:

def set_image(obj, image):
    '''Sets the image used as a background. Expects an instance of PIL.Image
    CAUTION: THIS OPERATION IS SLOW'''
    if image is None:
        # Sets the image to all black
        buff = bgl.Buffer(bgl.GL_BYTE, 3)  # Blank, really small image
        width, height = [1, 1]
    else:
        width, height = image.size
        imdata = numpy.asarray(image.convert('RGB')).ravel()  # SLOW
        buff = bgl.Buffer(bgl.GL_BYTE, width*height*3, imdata)

    image_buffer = bge.texture.ImageBuff(1, 1)  # Very small image
    image_buffer.load(buff, width, height)  # Overwritten with PIL one

    if 'TEX' not in obj:
        obj['TEX'] = bge.texture.Texture(obj, 0) # 0 is the texture ID
    tex = obj['TEX']
    tex.source = image_buffer
    tex.refresh(False)