diff --git a/include/aidge/backend/cpu.hpp b/include/aidge/backend/cpu.hpp
index 4d334e2a492962ab40efaf9bf1fe64682f225db2..cc1579ea9bb83a7d594bd0a524975800c583dcbb 100644
--- a/include/aidge/backend/cpu.hpp
+++ b/include/aidge/backend/cpu.hpp
@@ -23,6 +23,7 @@
 #include "aidge/backend/cpu/operator/LeakyReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/MatMulImpl.hpp"
 #include "aidge/backend/cpu/operator/PadImpl.hpp"
+#include "aidge/backend/cpu/operator/PowImpl.hpp"
 #include "aidge/backend/cpu/operator/ProducerImpl.hpp"
 #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
diff --git a/include/aidge/backend/cpu/operator/PowImpl.hpp b/include/aidge/backend/cpu/operator/PowImpl.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ea58aa2e51a8eea034dbebb71adefecfdcb336f
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/PowImpl.hpp
@@ -0,0 +1,50 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_CPU_OPERATOR_POWIMPL_H_
+#define AIDGE_CPU_OPERATOR_POWIMPL_H_
+
+#include "aidge/backend/OperatorImpl.hpp"
+#include "aidge/operator/Pow.hpp"
+#include "aidge/utils/Registrar.hpp"
+#include "aidge/utils/Types.h"
+#include <memory>
+#include <vector>
+
+namespace Aidge {
+// class Pow_Op;
+
+// compute kernel registry for forward and backward
+class PowImplForward_cpu
+    : public Registrable<PowImplForward_cpu, std::tuple<DataType, DataType, DataType>, void(const std::size_t, const void*, const void*,void*)> {
+};
+class PowImplBackward_cpu
+    : public Registrable<PowImplBackward_cpu, std::tuple<DataType, DataType, DataType>, void(const std::size_t, const void*, const void*, void*)> {
+};
+
+class PowImpl_cpu : public OperatorImpl {
+public:
+    PowImpl_cpu(const Pow_Op& op) : OperatorImpl(op) {}
+
+    static std::unique_ptr<PowImpl_cpu> create(const Pow_Op& op) {
+        return std::make_unique<PowImpl_cpu>(op);
+    }
+
+    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    void forward() override;
+};
+
+namespace {
+static Registrar<Pow_Op> registrarPowImpl_cpu("cpu", Aidge::PowImpl_cpu::create);
+}
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_POWIMPL_H_ */
diff --git a/include/aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0bf60dfea62057bfaac7e78c9cefe380285833a3
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp
@@ -0,0 +1,51 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_CPU_OPERATOR_POWIMPL_FORWARD_KERNEL_H_
+#define AIDGE_CPU_OPERATOR_POWIMPL_FORWARD_KERNEL_H_
+
+#include "aidge/utils/Registrar.hpp"
+#include <cmath>
+#include <iostream>
+#include "aidge/backend/cpu/operator/PowImpl.hpp"
+
+namespace Aidge {
+template <class I1, class I2, class O>
+void PowImpl_cpu_forward_kernel(std::size_t inputLenght,
+                                     const void* input1_,
+                                     const void* input2_,
+                                     void* output_) {
+
+    const I1* input_1 = static_cast<const I1*>(input1_);
+    const I2* input_2 = static_cast<const I2*>(input2_);
+    O* output = static_cast<O*>(output_);
+
+    for (std::size_t i = 0; i < inputLenght; ++i) {
+        //TODO: handle pow of two tensors the same size
+        output[i] = std::pow(input_1[i], input_2[0]);
+    }
+}
+
+namespace {
+// TODO: add support for pow(float, int)
+static Registrar<PowImplForward_cpu> registrarPowImplForward_cpu_Float32(
+        {DataType::Float32, DataType::Float32, DataType::Float32},
+        Aidge::PowImpl_cpu_forward_kernel<float, float, float>);
+static Registrar<PowImplForward_cpu> registrarPowImplForward_cpu_Int32(
+        {DataType::Int32, DataType::Int32, DataType::Int32},
+        Aidge::PowImpl_cpu_forward_kernel<int, int, int>);
+static Registrar<PowImplForward_cpu> registrarPowImplForward_cpu_Float64(
+        {DataType::Float64, DataType::Float64, DataType::Float64},
+        Aidge::PowImpl_cpu_forward_kernel<double, double, double>);
+}  // namespace
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_POWIMPL_FORWARD_KERNEL_H_ */
diff --git a/src/operator/PowImpl.cpp b/src/operator/PowImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0b655d39b3b23935ac7dc72971a72e4c219f1bc
--- /dev/null
+++ b/src/operator/PowImpl.cpp
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <cassert>
+#include <chrono>  // std::chrono::milliseconds
+#include <numeric> // std::accumulate
+#include <thread>  // std::this_thread::sleep_for
+#include <vector>
+
+#include "aidge/operator/Pow.hpp"
+#include "aidge/utils/Types.h"
+
+#include "aidge/backend/cpu/operator/PowImpl.hpp"
+#include "aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp"
+
+Aidge::NbElts_t Aidge::PowImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+    // this implementation can be in-place
+    return 0;
+}
+
+void Aidge::PowImpl_cpu::forward() {
+    assert(mOp.getInput(0) && "missing input #0");
+    assert(mOp.getInput(1) && "missing input #1");
+
+    // Find the correct kernel type
+    auto kernelFunc = Registrar<PowImplForward_cpu>::create({
+        mOp.getInput(0)->dataType(),
+        mOp.getInput(1)->dataType(),
+        mOp.getOutput(0)->dataType()});
+
+    // Call kernel
+    kernelFunc(std::static_pointer_cast<Tensor>(mOp.getInput(0))->size(),
+        mOp.getInput(0)->getImpl()->rawPtr(),
+        mOp.getInput(1)->getImpl()->rawPtr(),
+        mOp.getOutput(0)->getImpl()->rawPtr());
+}
diff --git a/unit_tests/operator/Test_PowImpl.cpp b/unit_tests/operator/Test_PowImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0cb04137644be78a09b179fd1a7a71f96c2d4903
--- /dev/null
+++ b/unit_tests/operator/Test_PowImpl.cpp
@@ -0,0 +1,128 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <catch2/catch_test_macros.hpp>
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/operator/Pow.hpp"
+
+#include "aidge/backend/cpu.hpp"
+
+#include <memory>
+
+using namespace Aidge;
+
+TEST_CASE("[cpu/operator] Pow(forward)") {
+    SECTION("2D Tensor") {
+        std::shared_ptr<Tensor> input_1 = std::make_shared<Tensor>(Array2D<float,2,2> {
+            {
+                {0.42139274, 0.51524192},
+                {0.85247433, 0.13432795}
+            }
+        });
+        std::shared_ptr<Tensor> input_2 =  std::make_shared<Tensor>(Array2D<float,1,1>{{2.0}});
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array2D<float,2,2> {
+            {
+                {0.17757183, 0.26547423},
+                {0.72671247, 0.01804400}
+            }
+        });
+
+        std::shared_ptr<Node> myPow = Pow();
+        myPow->getOperator()->setDatatype(DataType::Float32);
+        myPow->getOperator()->setBackend("cpu");
+        myPow->getOperator()->associateInput(0, input_1);
+        myPow->getOperator()->associateInput(1, input_2);
+        myPow->getOperator()->computeOutputDims();
+        myPow->forward();
+
+        float* resPtr = static_cast<float*>(myPow->getOperator()->getOutput(0)->getImpl()->rawPtr());
+        float* expectedPtr = static_cast<float*>(expectedOutput->getImpl()->rawPtr());
+        for (std::size_t i = 0; i< 4; ++i) {
+            REQUIRE(std::abs(resPtr[i]-expectedPtr[i]) < 0.00001);
+        }
+
+    }
+
+    SECTION("4D Tensor") {
+        std::shared_ptr<Tensor> input_1 = std::make_shared<Tensor>(Array4D<float,2,3,3,3> {
+            {
+                {
+                    {{0.80191749, 0.45388508, 0.86550850},
+                     {0.47226250, 0.55809456, 0.59451854},
+                     {0.45497441, 0.02653158, 0.44041735}},
+                    {{0.30726379, 0.73146582, 0.46462774},
+                     {0.30268502, 0.78075552, 0.65154958},
+                     {0.91332406, 0.62448132, 0.53238851}},
+                    {{0.13917381, 0.43061519, 0.30198061},
+                     {0.12880909, 0.08995515, 0.29609048},
+                     {0.46449280, 0.47559714, 0.24193990}}
+                },
+                {
+                    {{0.87349969, 0.51625526, 0.16921073},
+                     {0.95035923, 0.10066575, 0.56729180},
+                     {0.84686232, 0.05965143, 0.03635806}},
+                    {{0.61107808, 0.59954077, 0.45627308},
+                     {0.84114522, 0.77186388, 0.37427086},
+                     {0.13415480, 0.00617349, 0.84260136}},
+                    {{0.55090177, 0.57292056, 0.29158932},
+                     {0.67131883, 0.96988875, 0.69545972},
+                     {0.80979776, 0.18238151, 0.19527155}}
+                }
+            }
+        });
+        std::shared_ptr<Tensor> input_2 =  std::make_shared<Tensor>(Array2D<float,1,1>{{2.0}});
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<float,2,3,3,3> {
+            {
+                {
+                    {{6.43071651e-01, 2.06011668e-01, 7.49104977e-01},
+                     {2.23031864e-01, 3.11469525e-01, 3.53452295e-01},
+                     {2.07001716e-01, 7.03924568e-04, 1.93967447e-01}},
+
+                    {{9.44110379e-02, 5.35042226e-01, 2.15878934e-01},
+                     {9.16182250e-02, 6.09579206e-01, 4.24516857e-01},
+                     {8.34160864e-01, 3.89976919e-01, 2.83437520e-01}},
+
+                    {{1.93693489e-02, 1.85429439e-01, 9.11922902e-02},
+                     {1.65917836e-02, 8.09192937e-03, 8.76695737e-02},
+                     {2.15753555e-01, 2.26192638e-01, 5.85349165e-02}}
+                },
+                {
+                    {{7.63001740e-01, 2.66519487e-01, 2.86322720e-02},
+                     {9.03182685e-01, 1.01335924e-02, 3.21819991e-01},
+                     {7.17175782e-01, 3.55829368e-03, 1.32190844e-03}},
+
+                    {{3.73416424e-01, 3.59449148e-01, 2.08185121e-01},
+                     {7.07525253e-01, 5.95773816e-01, 1.40078679e-01},
+                     {1.79975089e-02, 3.81119971e-05, 7.09977031e-01}},
+
+                    {{3.03492755e-01, 3.28237981e-01, 8.50243345e-02},
+                     {4.50668961e-01, 9.40684199e-01, 4.83664215e-01},
+                     {6.55772448e-01, 3.32630165e-02, 3.81309800e-02}}
+                }
+            }
+        });
+
+        std::shared_ptr<Node> myPow = Pow();
+        myPow->getOperator()->setDatatype(DataType::Float32);
+        myPow->getOperator()->setBackend("cpu");
+        myPow->getOperator()->associateInput(0, input_1);
+        myPow->getOperator()->associateInput(1, input_2);
+        myPow->getOperator()->computeOutputDims();
+        myPow->forward();
+
+        float* resPtr = static_cast<float*>(myPow->getOperator()->getOutput(0)->getImpl()->rawPtr());
+        float* expectedPtr = static_cast<float*>(expectedOutput->getImpl()->rawPtr());
+        for (std::size_t i = 0; i< 54; ++i) {
+            REQUIRE(std::abs(resPtr[i]-expectedPtr[i]) < 0.00001);
+        }
+    }
+}
\ No newline at end of file