To get good torque at low speeds, you may need to implement sensorless speed feedback.
Basically, the average EMF generated by a brushed DC motor during the PWM Off period is proportional to the speed. You'll need a series resistor to an analog switch gated by the PWM feeding a capacitor (to ground) to average the EMF, then a low input leakage current OPAMP buffer to feed a MCU ADC input, and possibly scale the voltage for more resolution within the desired speed range. You then need to write a proportional control algorithm to attempt to hold a constant speed by varying the PWM duty cycle. If the EMF drops to zero, the motor is stalled, and in the absence of current sensing, to avoid burnout, you should stop driving it - but unless the winch has a ratchet mechanism, beware of run-back which will cause the EMF to go negative.
If you add current sensing, you can maintain torque while stalled, but if the motor is fan cooled, you need to derate the holding current significantly (from the max continuous operating current) to avoid burnout due to no cooling air flow. A sealed motor doesn't need as much derating but still needs some as there will be little air flow within its housing to transfer heat from the rotor to its shell.
N.B. the effective time constant of the RC averaging network varys with the PWM duty cycle, so if you want to use this over a wide PWM duty cycle range you'll probably need to switch in different averaging capacitors.