diff --git a/modules/video/src/lkpyramid.cpp b/modules/video/src/lkpyramid.cpp
index 739bb10780..8979d74437 100644
--- a/modules/video/src/lkpyramid.cpp
+++ b/modules/video/src/lkpyramid.cpp
@@ -849,6 +849,9 @@ namespace
                 return false;
             if (maxLevel < 0 || winSize.width <= 2 || winSize.height <= 2)
                 return false;
+            if (winSize.width < 16 || winSize.height < 16 ||
+                winSize.width > 24 || winSize.height > 24)
+                return false;
             calcPatchSize();
             if (patch.x <= 0 || patch.x >= 6 || patch.y <= 0 || patch.y >= 6)
                 return false;
diff --git a/modules/video/src/opencl/pyrlk.cl b/modules/video/src/opencl/pyrlk.cl
index 80ec48a74e..dd8f368fb5 100644
--- a/modules/video/src/opencl/pyrlk.cl
+++ b/modules/video/src/opencl/pyrlk.cl
@@ -260,7 +260,7 @@ inline void GetPatch(image2d_t J, float x, float y,
 
 inline void GetError(image2d_t J, const float x, const float y, const float* Pch, float* errval)
 {
-    float diff = read_imagef(J, sampler, (float2)(x,y)).x-*Pch;
+    float diff = (((read_imagef(J, sampler, (float2)(x,y)).x * 16384) + 256) / 512) - (((*Pch * 16384) + 256) /512);
     *errval += fabs(diff);
 }
 
@@ -526,6 +526,6 @@ __kernel void lkSparse(image2d_t I, image2d_t J,
         nextPts[gid] = prevPt;
 
         if (calcErr)
-            err[gid] = smem1[0] / (float)(c_winSize_x * c_winSize_y);
+            err[gid] = smem1[0] / (float)(32 * c_winSize_x * c_winSize_y);
     }
 }
diff --git a/modules/video/test/ocl/test_optflowpyrlk.cpp b/modules/video/test/ocl/test_optflowpyrlk.cpp
index 3c264a5e41..40b626150c 100644
--- a/modules/video/test/ocl/test_optflowpyrlk.cpp
+++ b/modules/video/test/ocl/test_optflowpyrlk.cpp
@@ -77,6 +77,7 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
 {
     static const int npoints = 1000;
     static const float eps = 0.03f;
+    static const float erreps = 0.1f;
 
     cv::Mat frame0 = readImage("optflow/RubberWhale1.png", cv::IMREAD_GRAYSCALE);
     ASSERT_FALSE(frame0.empty());
@@ -104,6 +105,8 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
     ASSERT_EQ(cpuStatusCPU.size(), status.size());
 
     size_t mistmatch = 0;
+    size_t errmatch = 0;
+
     for (size_t i = 0; i < nextPts.size(); ++i)
     {
         if (status[i] != cpuStatusCPU[i])
@@ -121,13 +124,22 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
             float errdiff = 0.0f;
 
             if (!eq || errdiff > 1e-1)
+            {
                 ++mistmatch;
+                continue;
+            }
+
+            eq = std::abs(cpuErr[i] - err[i]) < 0.01;
+            if(!eq)
+                ++errmatch;
         }
     }
 
     double bad_ratio = static_cast<double>(mistmatch) / (nextPts.size());
+    double err_ratio = static_cast<double>(errmatch) / (nextPts.size());
 
     ASSERT_LE(bad_ratio, eps);
+    ASSERT_LE(err_ratio, erreps);
 }
 
 OCL_INSTANTIATE_TEST_CASE_P(Video, PyrLKOpticalFlow,