diff --git a/tests/validation/CPP/HarrisCornerDetector.cpp b/tests/validation/CPP/HarrisCornerDetector.cpp
new file mode 100644
index 0000000..3babfee
--- /dev/null
+++ b/tests/validation/CPP/HarrisCornerDetector.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "HarrisCornerDetector.h"
+
+#include "Utils.h"
+#include "tests/validation/CPP/NonMaximaSuppression.h"
+#include "tests/validation/CPP/Sobel.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+template <typename T>
+std::tuple<SimpleTensor<T>, SimpleTensor<T>, float> compute_sobel(const SimpleTensor<uint8_t> &src, int gradient_size, int block_size, BorderMode border_mode, uint8_t constant_border_value)
+{
+    SimpleTensor<T> grad_x;
+    SimpleTensor<T> grad_y;
+    float           norm_factor = 0.f;
+
+    std::tie(grad_x, grad_y) = sobel<T>(src, gradient_size, border_mode, constant_border_value);
+
+    switch(gradient_size)
+    {
+        case 3:
+            norm_factor = 1.f / (4 * 255 * block_size);
+            break;
+        case 5:
+            norm_factor = 1.f / (16 * 255 * block_size);
+            break;
+        case 7:
+            norm_factor = 1.f / (64 * 255 * block_size);
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Gradient size not supported.");
+    }
+
+    return std::make_tuple(grad_x, grad_y, norm_factor);
+}
+
+template <typename T, typename U>
+std::vector<KeyPoint> harris_corner_detector_impl(const SimpleTensor<U> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                                  U constant_border_value)
+{
+    ARM_COMPUTE_ERROR_ON(block_size != 3 && block_size != 5 && block_size != 7);
+
+    SimpleTensor<T> grad_x;
+    SimpleTensor<T> grad_y;
+    float           norm_factor = 0.f;
+
+    // Sobel
+    std::tie(grad_x, grad_y, norm_factor) = compute_sobel<T>(src, gradient_size, block_size, border_mode, constant_border_value);
+
+    SimpleTensor<float> scores(src.shape(), DataType::F32);
+    ValidRegion         scores_region = shape_to_valid_region(scores.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(gradient_size / 2 + block_size / 2));
+
+    // Calculate scores
+    for(int i = 0; i < scores.num_elements(); ++i)
+    {
+        Coordinates src_coord = index2coord(src.shape(), i);
+        Coordinates block_top_left{ src_coord.x() - block_size / 2, src_coord.y() - block_size / 2 };
+        Coordinates block_bottom_right{ src_coord.x() + block_size / 2, src_coord.y() + block_size / 2 };
+
+        if(!is_in_valid_region(scores_region, src_coord))
+        {
+            scores[i] = 0.f;
+            continue;
+        }
+
+        float Gx2 = 0.f;
+        float Gy2 = 0.f;
+        float Gxy = 0.f;
+
+        // Calculate Gx^2, Gy^2 and Gxy within the given window
+        for(int y = src_coord.y() - block_size / 2; y <= src_coord.y() + block_size / 2; ++y)
+        {
+            for(int x = src_coord.x() - block_size / 2; x <= src_coord.x() + block_size / 2; ++x)
+            {
+                Coordinates block_coord(x, y);
+
+                const float norm_x = tensor_elem_at(grad_x, block_coord, border_mode, static_cast<T>(constant_border_value)) * norm_factor;
+                const float norm_y = tensor_elem_at(grad_y, block_coord, border_mode, static_cast<T>(constant_border_value)) * norm_factor;
+
+                Gx2 += std::pow(norm_x, 2);
+                Gy2 += std::pow(norm_y, 2);
+                Gxy += norm_x * norm_y;
+            }
+        }
+
+        const float trace2   = std::pow(Gx2 + Gy2, 2);
+        const float det      = Gx2 * Gy2 - std::pow(Gxy, 2);
+        const float response = det - sensitivity * trace2;
+
+        if(response > threshold)
+        {
+            scores[i] = response;
+        }
+        else
+        {
+            scores[i] = 0.f;
+        }
+    }
+
+    // Suppress non-maxima candidates
+    SimpleTensor<float> suppressed_scores        = non_maxima_suppression(scores, border_mode != BorderMode::UNDEFINED ? BorderMode::CONSTANT : BorderMode::UNDEFINED, 0.f);
+    ValidRegion         suppressed_scores_region = shape_to_valid_region(suppressed_scores.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(gradient_size / 2 + block_size / 2 + 1));
+
+    // Create vector of candidate corners
+    std::vector<KeyPoint> corner_candidates;
+
+    for(int i = 0; i < suppressed_scores.num_elements(); ++i)
+    {
+        Coordinates coord = index2coord(suppressed_scores.shape(), i);
+
+        if(is_in_valid_region(suppressed_scores_region, coord) && suppressed_scores[i] > 0.f)
+        {
+            KeyPoint corner;
+            corner.x               = coord.x();
+            corner.y               = coord.y();
+            corner.tracking_status = 1;
+            corner.strength        = suppressed_scores[i];
+            corner.scale           = 0.f;
+            corner.orientation     = 0.f;
+            corner.error           = 0.f;
+
+            corner_candidates.emplace_back(corner);
+        }
+    }
+
+    // Sort descending by strength
+    std::sort(corner_candidates.begin(), corner_candidates.end(), [](const KeyPoint & a, const KeyPoint & b)
+    {
+        return a.strength > b.strength;
+    });
+
+    std::vector<KeyPoint> corners;
+    corners.reserve(corner_candidates.size());
+
+    // Only add corner if there is no stronger within min_dist
+    for(const KeyPoint &point : corner_candidates)
+    {
+        const auto strongest = std::find_if(corners.begin(), corners.end(), [&](const KeyPoint & other)
+        {
+            return std::sqrt((std::pow(point.x - other.x, 2) + std::pow(point.y - other.y, 2))) < min_dist;
+        });
+
+        if(strongest == corners.end())
+        {
+            corners.emplace_back(point);
+        }
+    }
+
+    corners.shrink_to_fit();
+
+    return corners;
+}
+} // namespace
+
+template <typename T>
+std::vector<KeyPoint> harris_corner_detector(const SimpleTensor<T> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                             T constant_border_value)
+{
+    if(gradient_size < 7)
+    {
+        return harris_corner_detector_impl<int16_t>(src, threshold, min_dist, sensitivity, gradient_size, block_size, border_mode, constant_border_value);
+    }
+    else
+    {
+        return harris_corner_detector_impl<int32_t>(src, threshold, min_dist, sensitivity, gradient_size, block_size, border_mode, constant_border_value);
+    }
+}
+
+template std::vector<KeyPoint> harris_corner_detector(const SimpleTensor<uint8_t> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                                      uint8_t constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
