I2C Master: How to read with repeated start condition?
This helped. Gave up on using the MCC stuff for this, other than the clicked-together basic peripheral init stuff. (Note that in the microchip official forum it was said the MCC I2C library is currently changing and not tested a lot)
I basically just added a further parameter to indicate whether I want to use stop,start; or restart (aka repeated start condition), making it so that for "restart" the write-block routine omits the STOP at the end, and the read-block routine calls restart() instead of start().
Also note that that code expects left-aligned slave addresses (Lshift 1).

http://picforum.ric323.com/viewtopic.php?f=76&amp;t=755#

Here an excerpt of the most relevant stuff, incl. those of my changes I mentioned - you might have to change things to qualify the correct register structs before the register names in this code, if you also use the MCC generated init code, despite then not using MCC for the actual business.
If you use the read-block routine and pass repeatStart=true, it will do repeated-start condition intead of stop,start. Otherwise, it will do stop,start. With this, I was able to read that device which would refuse to be read before, so the question is answered - just without using the MCC I2C state machine, instead rather bypassing it with direct register access.

// Send an I2C START
// Return 0 if all ok, 1 if bus collision
__bit i2c_start(void)
{
    BCLIF = 0;  //Clear 'Bus collision" flag
    SEN = 1;    //initiate a START cycle
    while (SEN);    //wait until it has been sent
    return BCLIF;   //return value of BCLIF flag
}

// Send an I2C STOP
void i2c_stop(void)
{
    PEN = 1;    //initiate a STOP cycle
    while (PEN);    //wait until it has been sent
}

// Send an I2C REPEATED START
void i2c_restart(void)
{
    RSEN = 1;    //initiate a REPEATED START cycle
    while (RSEN);    //wait until it has been sent
}

//Send one byte. Return 0 if ACK received, or 1 if NAK received
__bit i2c_sendbyte(unsigned char dat)
{
    SSPBUF = dat;
    while (R_W);    //wait until byte sent and ACK/NAK received
    return ACKSTAT;
}

//Receive one byte. ackflag=0 to send ACK, or 1 to send NAK in reply
unsigned char i2c_recvbyte(unsigned char ackflag)
{
    RCEN = 1;   // initiate a RECEIVE cycle
    ACKDT = ackflag;    //specify if we should send ACK or NAK after receiving
    while (RCEN);   //wait until RECEIVE has completed
    ACKEN = 1;  //initiate an ACK cycle
    while (ACKEN);  //wait until it has completed
    return SSPBUF;
}

//Send an array of data to an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK, 4 if slave data NAK
unsigned char i2c_writeblock(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, const unsigned char * bufptr, bool stop)
{
    if (i2c_start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision
    //send the I2C slave address (force R/W bit low)
    if (i2c_sendbyte(slave_address &amp; 0xFE))
    {
        i2c_stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //send the device register index
    if (i2c_sendbyte(start_reg))
    {
        i2c_stop(); //if register was NAKed, terminate the cycle
        return 3;   //and return error code
    }
    //send the data. buflen might be zero!
    for (; buflen&gt;0; --buflen)
    {
        if (i2c_sendbyte(*bufptr++))
        {
            i2c_stop(); //if register was NAKed, terminate the cycle
            return 4;   //and return error code
        }

    }
    if (stop)
      i2c_stop();
    return 0;   //no error
}

//Receive an array of data from an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK
unsigned char i2c_readblock(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, unsigned char * bufptr, bool repeatStart)
{
    //do a dummy zero length write cycle to set the register address
    unsigned char retval = i2c_writeblock(slave_address, start_reg,0,0, !repeatStart);
    if (retval)
    {
        return retval;  //abort if there was an error
    }

    if (repeatStart)
      i2c_restart(); // restart can't fail - if bus remains asserted, there can be no collision
    else
    //now start the READ cycle
      if (i2c_start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision

    //send the I2C slave address (force the R/W bit high)
    if (i2c_sendbyte(slave_address | 0x01))
    {
        i2c_stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //receive the data.
    for (; buflen&gt;0; --buflen)
    {
        unsigned char ackflag = (buflen == 1);   //1 if this is the last byte to receive =&gt; send NAK
        *bufptr++ = i2c_recvbyte(ackflag);
    }
    i2c_stop();
    return 0;   //no error
}