diff --git a/tests/validate_examples/graph_depthwiseconvolution.cpp b/tests/validate_examples/graph_depthwiseconvolution.cpp
new file mode 100644
index 0000000..cdad404
--- /dev/null
+++ b/tests/validate_examples/graph_depthwiseconvolution.cpp
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2019 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 "arm_compute/graph.h"
+
+#include "support/ToolchainSupport.h"
+
+#include "tests/NEON/Accessor.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/reference/DepthwiseConvolutionLayer.h"
+#include "tests/validation/reference/Permute.h"
+
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+#include "ValidateExample.h"
+#include "graph_validate_utils.h"
+
+#include <utility>
+
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+using namespace arm_compute::graph;
+using namespace arm_compute;
+using namespace arm_compute::test;
+using namespace arm_compute::test::validation;
+
+namespace
+{
+/** Depthwise Convolution command line options used to configure the graph examples
+ *
+ * (Similar to common options)
+ * The options in this object get populated when "parse()" is called on the parser used to construct it.
+ * The expected workflow is:
+ *
+ * CommandLineParser parser;
+ * CommonOptions options( parser );
+ * parser.parse(argc, argv);
+ */
+class DepthConvolutionOptions final : public CommonGraphValidateOptions
+{
+public:
+    explicit DepthConvolutionOptions(CommandLineParser &parser) noexcept
+        : CommonGraphValidateOptions(parser),
+          width(parser.add_option<SimpleOption<int>>("width", 9)),
+          height(parser.add_option<SimpleOption<int>>("height", 9)),
+          channels(parser.add_option<SimpleOption<int>>("channels", 1)),
+          batch(parser.add_option<SimpleOption<int>>("batch", 1)),
+          weights_width(parser.add_option<SimpleOption<int>>("weights_width", 3)),
+          weights_height(parser.add_option<SimpleOption<int>>("weights_height", 3)),
+          padding_top(parser.add_option<SimpleOption<int>>("padding_top", 0)),
+          padding_left(parser.add_option<SimpleOption<int>>("padding_left", 0)),
+          padding_bottom(parser.add_option<SimpleOption<int>>("padding_bottom", 0)),
+          padding_right(parser.add_option<SimpleOption<int>>("padding_right", 0)),
+          stride_x(parser.add_option<SimpleOption<int>>("stride_x", 1)),
+          stride_y(parser.add_option<SimpleOption<int>>("stride_y", 1)),
+          padding_mode(),
+          conv_mode(),
+          depth_multiplier(parser.add_option<SimpleOption<int>>("depth_multiplier", 1)),
+          data_layout(),
+          scale(parser.add_option<SimpleOption<float>>("scale", 1.0f)),
+          offset(parser.add_option<SimpleOption<int>>("offset", 0)),
+          weights_scale(parser.add_option<SimpleOption<float>>("weights_scale", 1.0f)),
+          weights_offset(parser.add_option<SimpleOption<int>>("weights_offset", 0)),
+          output_scale(parser.add_option<SimpleOption<float>>("output_scale", 1.0f)),
+          output_offset(parser.add_option<SimpleOption<int>>("output_offset", 0)),
+          input_range_low(parser.add_option<SimpleOption<uint64_t>>("input_range_low")),
+          input_range_high(parser.add_option<SimpleOption<uint64_t>>("input_range_high")),
+          weights_range_low(parser.add_option<SimpleOption<uint64_t>>("weights_range_low")),
+          weights_range_high(parser.add_option<SimpleOption<uint64_t>>("weights_range_high")),
+          input_npy(parser.add_option<SimpleOption<std::string>>("input_image")),
+          output_npy(parser.add_option<SimpleOption<std::string>>("reference_image")),
+          weights_npy(parser.add_option<SimpleOption<std::string>>("weights_npy")),
+          bias_npy(parser.add_option<SimpleOption<std::string>>("bias_image"))
+    {
+        const std::set<ConvolutionPaddingMode> available_padding_modes
+        {
+            ConvolutionPaddingMode::Valid,
+            ConvolutionPaddingMode::Same
+        };
+
+        const std::set<arm_compute::graph::DepthwiseConvolutionMethod> supported_convolution_methods
+        {
+            arm_compute::graph::DepthwiseConvolutionMethod::Default,
+            arm_compute::graph::DepthwiseConvolutionMethod::GEMV,
+            arm_compute::graph::DepthwiseConvolutionMethod::Optimized3x3,
+        };
+
+        const std::set<DataLayout> supported_data_layouts
+        {
+            DataLayout::NHWC,
+            DataLayout::NCHW,
+        };
+
+        padding_mode = parser.add_option<EnumOption<ConvolutionPaddingMode>>("padding_mode", available_padding_modes, ConvolutionPaddingMode::Valid);
+        conv_mode    = parser.add_option<EnumOption<arm_compute::graph::DepthwiseConvolutionMethod>>("convolution_method", supported_convolution_methods,
+                                                                                                     arm_compute::graph::DepthwiseConvolutionMethod::Default);
+        data_layout = parser.add_option<EnumOption<DataLayout>>("layout", supported_data_layouts, DataLayout::NHWC);
+
+        padding_mode->set_help("Set padding mode");
+        width->set_help("Set Input dimension width");
+        height->set_help("Set Input dimension height");
+        channels->set_help("Set Input dimension channels");
+        batch->set_help("Set Input dimension batch");
+        weights_width->set_help("Set weights_dimensions width");
+        weights_height->set_help("Set weights_dimensions height");
+        padding_top->set_help("Set padding top");
+        padding_bottom->set_help("Set padding bottom");
+        padding_left->set_help("Set padding left");
+        padding_right->set_help("Set padding right");
+        stride_x->set_help("Set padding stride x");
+        stride_y->set_help("Set padding stride y");
+        conv_mode->set_help("Set convolution method");
+        data_layout->set_help("Data layout to use");
+        scale->set_help("Quantization scale from QASYMM8");
+        offset->set_help("Quantization offset from QASYMM8");
+        output_scale->set_help("Quantization scale from QASYMM8");
+        output_offset->set_help("Quantization offset from QASYMM8");
+        input_npy->set_help("Use input .npy instead");
+        output_npy->set_help("Use .npy as a reference");
+        input_range_low->set_help("Lower bound for input randomization range");
+        input_range_high->set_help("Lower bound for input randomization range");
+        weights_scale->set_help("Quantization scale from QASYMM8");
+        weights_offset->set_help("Quantization offset from QASYMM8");
+        weights_range_low->set_help("Lower bound for input randomization range");
+        weights_range_high->set_help("Lower bound for input randomization range");
+        depth_multiplier->set_help("Depth multiplier");
+    }
+
+    /** Fill out the supplied parameters with user supplied parameters
+     *
+     * @param[out] os            Output stream.
+     * @param[in]  common_params Example parameters to output
+     *
+     * @return None.
+     */
+    void consume_parameters(ExampleParams &common_params)
+    {
+        common_params.input.width             = width->value();
+        common_params.input.height            = height->value();
+        common_params.input.fm                = channels->value();
+        common_params.input.batch             = batch->value();
+        common_params.input.quant_info.scale  = scale->value();
+        common_params.input.quant_info.offset = offset->value();
+        common_params.input.npy               = input_npy->value();
+        common_params.input.range_low         = input_range_low->value();
+        common_params.input.range_high        = input_range_high->value();
+
+        common_params.weights.width             = weights_width->value();
+        common_params.weights.height            = weights_height->value();
+        common_params.weights.npy               = weights_npy->value();
+        common_params.weights.range_low         = weights_range_low->value();
+        common_params.weights.range_high        = weights_range_high->value();
+        common_params.weights.quant_info.scale  = weights_scale->value();
+        common_params.weights.quant_info.offset = weights_offset->value();
+
+        common_params.bias.npy = bias_npy->value();
+
+        common_params.output.quant_info.scale  = output_scale->value();
+        common_params.output.quant_info.offset = output_offset->value();
+        common_params.output.npy               = output_npy->value();
+
+        common_params.convolution.padding_mode     = padding_mode->value();
+        common_params.convolution.padding_top      = padding_top->value();
+        common_params.convolution.padding_bottom   = padding_bottom->value();
+        common_params.convolution.padding_left     = padding_left->value();
+        common_params.convolution.padding_right    = padding_right->value();
+        common_params.convolution.padding_stride_x = stride_x->value();
+        common_params.convolution.padding_stride_y = stride_y->value();
+        common_params.convolution.depth_multiplier = depth_multiplier->value();
+
+        common_params.data_type                = data_type->value();
+        common_params.data_layout              = data_layout->value();
+        common_params.depth_convolution_method = conv_mode->value();
+    }
+
+    void print_parameters(::std::ostream &os, const ExampleParams &common_params) override
+    {
+        os << "Threads : " << common_params.common_params.threads << std::endl;
+        os << "Target : " << common_params.common_params.target << std::endl;
+        os << "Data type : " << common_params.data_type << std::endl;
+        os << "Input dimensions(X,Y, Channels, Batch) : (" << common_params.input.width << "," << common_params.input.height << "," << common_params.input.fm << "," << common_params.input.batch << ")"
+           << std::endl;
+        os << "Weight dimensions(X,Y, Channels(same as input)) : (" << common_params.weights.width << "," << common_params.weights.height << "," << common_params.input.fm << ","
+           << ")" << std::endl;
+        os << "Padding(top, bottom, left, right) (stride x, stride y) : (" << common_params.convolution.padding_top << "," << common_params.convolution.padding_bottom << "," <<
+           common_params.convolution.padding_left << "," << common_params.convolution.padding_right << ") (" << common_params.convolution.padding_stride_x << "," << common_params.convolution.padding_stride_y <<
+           ")" << std::endl;
+        os << "Padding Mode: " << common_params.convolution.padding_mode << std::endl;
+        os << "Convolution Method: " << common_params.depth_convolution_method << std::endl;
+        os << "Depth multiplier: " << common_params.convolution.depth_multiplier;
+    }
+
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    DepthConvolutionOptions(const DepthConvolutionOptions &) = delete;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    DepthConvolutionOptions &operator=(const DepthConvolutionOptions &) = delete;
+    /** Allow instances of this class to be moved */
+    DepthConvolutionOptions(DepthConvolutionOptions &&) noexcept(true) = default;
+    /** Allow instances of this class to be moved */
+    DepthConvolutionOptions &operator=(DepthConvolutionOptions &&) noexcept(true) = default;
+    /** Default destructor */
+    ~DepthConvolutionOptions() override = default;
+
+    SimpleOption<int>                                          *width;              /**< Input width */
+    SimpleOption<int>                                          *height;             /**< Input height */
+    SimpleOption<int>                                          *channels;           /**< Input channels */
+    SimpleOption<int>                                          *batch;              /**< Input batch */
+    SimpleOption<int>                                          *weights_width;      /**< weights width */
+    SimpleOption<int>                                          *weights_height;     /**< weights height */
+    SimpleOption<int>                                          *padding_top;        /**< Padding top */
+    SimpleOption<int>                                          *padding_left;       /**< Padding left */
+    SimpleOption<int>                                          *padding_bottom;     /**< Padding bottom */
+    SimpleOption<int>                                          *padding_right;      /**< Padding right */
+    SimpleOption<int>                                          *stride_x;           /**< Padding stride x */
+    SimpleOption<int>                                          *stride_y;           /**< Padding stride y */
+    EnumOption<ConvolutionPaddingMode>                         *padding_mode;       /**< Padding mode */
+    EnumOption<arm_compute::graph::DepthwiseConvolutionMethod> *conv_mode;          /**< Convolution method */
+    SimpleOption<int>                                          *depth_multiplier;   /**< Depth multiplier */
+    EnumOption<arm_compute::DataLayout>                        *data_layout;        /**< Graph data layout */
+    SimpleOption<float>                                        *scale;              /**< Input Quantization scale from QASYMM8 */
+    SimpleOption<int>                                          *offset;             /**< Input Quantization offset from QASYMM8 */
+    SimpleOption<float>                                        *weights_scale;      /**< Weights Quantization scale from QASYMM8 */
+    SimpleOption<int>                                          *weights_offset;     /**< Weights Quantization offset from QASYMM8 */
+    SimpleOption<float>                                        *output_scale;       /**< Output Quantization scale from QASYMM8 */
+    SimpleOption<int>                                          *output_offset;      /**< Output Quantization offset from QASYMM8 */
+    SimpleOption<uint64_t>                                     *input_range_low;    /**< Lower bound for input randomization range */
+    SimpleOption<uint64_t>                                     *input_range_high;   /**< Upper bound for input randomization range */
+    SimpleOption<uint64_t>                                     *weights_range_low;  /**< Lower bound for weights randomization range */
+    SimpleOption<uint64_t>                                     *weights_range_high; /**< Upper bound for weights randomization range */
+
+    SimpleOption<std::string> *input_npy;   /**< Use input .npy image */
+    SimpleOption<std::string> *output_npy;  /**< Use output .npy image to verify*/
+    SimpleOption<std::string> *weights_npy; /**< Use weights .npy image */
+    SimpleOption<std::string> *bias_npy;    /**< Use bias .npy image */
+};
+
+/** DepthwiseConvolutionLayer Graph example validation accessor class */
+template <typename D>
+class DepthConvolutionVerifyAccessor final : public VerifyAccessor<D>
+{
+public:
+    using BaseClassType = VerifyAccessor<D>;
+    using BaseClassType::BaseClassType;
+    using BaseClassType::_params;
+    using TBias = typename std::conditional<std::is_same<typename std::decay<D>::type, uint8_t>::value, int32_t, D>::type;
+
+public:
+    SimpleTensor<D> reference(SimpleTensor<D> &src, SimpleTensor<D> &weights, SimpleTensor<TBias> &bias, const TensorShape &output_shape) override
+    {
+        // Calculate padding information
+        const PadStrideInfo padding_info = calculate_convolution_padding(_params);
+
+        //Calculate reference
+        return reference::depthwise_convolution<D>(src, weights, bias, output_shape, padding_info,
+                                                   _params.convolution.depth_multiplier,
+                                                   Size2D(1U, 1U),
+                                                   _params.output.quant_info);
+    }
+
+    float relative_tolerance() override
+    {
+        const std::map<arm_compute::graph::Target, const std::map<DataType, float>> relative_tolerance
+        {
+            {
+                arm_compute::graph::Target::CL,
+                {   { DataType::F16, 0.01f },
+                    { DataType::F32, 0.01f },
+                    { DataType::QASYMM8, 0.0f }
+                }
+            },
+            {
+                arm_compute::graph::Target::NEON,
+                {   { DataType::F16, 0.01f },
+                    { DataType::F32, 0.01f },
+                    { DataType::QASYMM8, 1.0f }
+                }
+            }
+        };
+
+        return relative_tolerance.at(_params.common_params.target).at(_params.data_type);
+    }
+
+    float absolute_tolerance() override
+    {
+        const std::map<Target, const std::map<DataType, float>> absolute_tolerance
+        {
+            {
+                Target::CL,
+                {   { DataType::F16, 0.0f },
+                    { DataType::F32, 0.0000f },
+                    { DataType::QASYMM8, 0.0f }
+                }
+            },
+            {
+                Target::NEON,
+                {   { DataType::F16, 0.2f },
+                    { DataType::F32, 0.002f },
+                    { DataType::QASYMM8, 0.0f }
+                }
+            }
+        };
+
+        return absolute_tolerance.at(_params.common_params.target).at(_params.data_type);
+    }
+
+    float tolerance_number() override
+    {
+        const std::map<Target, const std::map<DataType, float>> absolute_tolerance
+        {
+            {
+                Target::CL,
+                {   { DataType::F16, 0.05f },
+                    { DataType::F32, 0.00f },
+                    { DataType::QASYMM8, 0.0f }
+                }
+            },
+            {
+                Target::NEON,
+                {   { DataType::F16, 0.05f },
+                    { DataType::F32, 0.0f },
+                    { DataType::QASYMM8, 0.0f }
+                }
+            }
+        };
+
+        return absolute_tolerance.at(_params.common_params.target).at(_params.data_type);
+    }
+};
+
+} // namespace
+
+class GraphDepthwiseConvolutionValidateExample final : public GraphValidateExample<DepthwiseConvolutionLayer, DepthConvolutionOptions, DepthConvolutionVerifyAccessor>
+{
+    using GraphValidateExample::graph;
+
+public:
+    GraphDepthwiseConvolutionValidateExample()
+        : GraphValidateExample("DepthWiseConvolution Graph example")
+    {
+    }
+
+    DepthwiseConvolutionLayer GraphFunctionLayer(ExampleParams &params) override
+    {
+        const PixelValue lower = PixelValue(params.input.range_low, params.data_type, params.input.quant_info);
+        const PixelValue upper = PixelValue(params.input.range_high, params.data_type, params.input.quant_info);
+
+        const PixelValue weights_lower = PixelValue(params.weights.range_low, params.data_type, params.weights.quant_info);
+        const PixelValue weights_upper = PixelValue(params.weights.range_high, params.data_type, params.weights.quant_info);
+
+        // Calculate padding information
+        const PadStrideInfo padding_info = calculate_convolution_padding(params);
+
+        return DepthwiseConvolutionLayer(params.weights.width, params.weights.height,
+                                         get_accessor(params.weights, weights_lower, weights_upper, 1),
+                                         get_accessor(params.bias, lower, upper, 2),
+                                         padding_info, params.convolution.depth_multiplier, params.weights.quant_info, params.output.quant_info);
+    }
+};
+
+/** Main program for Graph Depthwise Convolution test
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments ( Input dimensions [width, height, channels, batch]
+ *                             Weights dimensions [width, height, channels]
+ *                             Padding [top,bottom,left,right, Stride x, Stride y, mode [Valid / Same / Manual] )
+ *                             Convolution Method[ Default/GEMV/Optimized3x3]
+ *                             Verification[tolerance_number,absolute_tolerance,relative_tolerance] )
+ *
+ */
+int main(int argc, char **argv)
+{
+    return arm_compute::utils::run_example<GraphDepthwiseConvolutionValidateExample>(argc, argv);
+}
