diff --git a/mlir/include/mlir-c/Dialect/Polynomial.h b/mlir/include/mlir-c/Dialect/Polynomial.h
new file mode 100644
index 0000000000000..31fb817cf534c
--- /dev/null
+++ b/mlir/include/mlir-c/Dialect/Polynomial.h
@@ -0,0 +1,47 @@
+//===-- mlir-c/Dialect/Polynomial.h - C API for Polynomial --------*- C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+// Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_C_DIALECT_POLYNOMIAL_H
+#define MLIR_C_DIALECT_POLYNOMIAL_H
+
+#include "mlir/CAPI/Wrap.h"
+#include "mlir/Dialect/Polynomial/IR/Polynomial.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(Polynomial, polynomial);
+
+#define DEFINE_C_API_STRUCT(name, storage)                                     \
+  struct name {                                                                \
+    storage *ptr;                                                              \
+  };                                                                           \
+  typedef struct name name
+
+DEFINE_C_API_STRUCT(MlirIntMonomial, void);
+
+#undef DEFINE_C_API_STRUCT
+
+DEFINE_C_API_PTR_METHODS(MlirIntMonomial, mlir::polynomial::IntMonomial);
+
+MLIR_CAPI_EXPORTED MlirIntMonomial mlirPolynomialGetIntMonomial(int64_t coeff,
+                                                                uint64_t expo);
+
+MLIR_CAPI_EXPORTED int64_t
+mlirPolynomialIntMonomialGetCoefficient(MlirIntMonomial intMonomial);
+
+MLIR_CAPI_EXPORTED uint64_t
+mlirPolynomialIntMonomialGetExponent(MlirIntMonomial intMonomial);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MLIR_C_DIALECT_POLYNOMIAL_H
diff --git a/mlir/lib/Bindings/Python/DialectPolynomial.cpp b/mlir/lib/Bindings/Python/DialectPolynomial.cpp
new file mode 100644
index 0000000000000..f0832d400e8c5
--- /dev/null
+++ b/mlir/lib/Bindings/Python/DialectPolynomial.cpp
@@ -0,0 +1,102 @@
+//===- DialectPolynomial.cpp - 'polynomial' dialect submodule -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir-c/Dialect/Polynomial.h"
+#include "mlir-c/IR.h"
+#include "mlir/Bindings/Python/PybindAdaptors.h"
+
+#include <pybind11/pybind11.h>
+#include <vector>
+
+namespace py = pybind11;
+using namespace llvm;
+using namespace mlir;
+using namespace mlir::python::adaptors;
+
+class PyIntMonomial {
+public:
+  PyIntMonomial(MlirIntMonomial intMonomial) : intMonomial(intMonomial) {}
+  PyIntMonomial(int64_t coeff, uint64_t expo)
+      : intMonomial(mlirPolynomialGetIntMonomial(coeff, expo)) {}
+  operator MlirIntMonomial() const { return intMonomial; }
+  MlirIntMonomial get() { return intMonomial; }
+
+  int64_t getCoefficient() {
+    return mlirPolynomialIntMonomialGetCoefficient(this->get());
+  }
+
+  uint64_t getExponent() {
+    return mlirPolynomialIntMonomialGetExponent(this->get());
+  }
+
+private:
+  MlirIntMonomial intMonomial;
+};
+
+#define MLIR_PYTHON_CAPSULE_INT_POLYNOMIAL                                     \
+  MAKE_MLIR_PYTHON_QUALNAME("dialects.polynomial.IntMonomial._CAPIPtr")
+
+static inline MlirIntMonomial
+mlirPythonCapsuleToIntMonomial(PyObject *capsule) {
+  void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_INT_POLYNOMIAL);
+  MlirIntMonomial intMonomial = {ptr};
+  return intMonomial;
+}
+
+static inline PyObject *
+mlirPythonIntMonomialToCapsule(MlirIntMonomial intMonomial) {
+  return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(intMonomial),
+                       MLIR_PYTHON_CAPSULE_INT_POLYNOMIAL, nullptr);
+}
+
+static inline bool mlirIntMonomialIsNull(MlirIntMonomial intMonomial) {
+  return !intMonomial.ptr;
+}
+
+namespace pybind11 {
+namespace detail {
+
+/// Casts object <-> MlirIntMonomial.
+template <>
+struct type_caster<MlirIntMonomial> {
+  PYBIND11_TYPE_CASTER(MlirIntMonomial, _("MlirIntMonomial"));
+  bool load(handle src, bool) {
+    py::object capsule = mlirApiObjectToCapsule(src);
+    value = mlirPythonCapsuleToIntMonomial(capsule.ptr());
+    return !mlirIntMonomialIsNull(value);
+  }
+
+  static handle cast(MlirIntMonomial v, return_value_policy, handle) {
+    py::object capsule =
+        py::reinterpret_steal<py::object>(mlirPythonIntMonomialToCapsule(v));
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("dialects.polynomial"))
+        .attr("IntMonomial")
+        .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
+        .release();
+  }
+};
+} // namespace detail
+} // namespace pybind11
+
+PYBIND11_MODULE(_mlirDialectsPolynomial, m) {
+  m.doc() = "MLIR Polynomial dialect";
+
+  py::class_<PyIntMonomial>(m, "IntMonomial", py::module_local())
+      .def(py::init<PyIntMonomial &>())
+      .def(py::init<MlirIntMonomial>())
+      .def(py::init<int64_t, uint64_t>())
+      .def_property_readonly("coefficient", &PyIntMonomial::getCoefficient)
+      .def_property_readonly("exponent", &PyIntMonomial::getExponent)
+      .def("__str__", [](PyIntMonomial &self) {
+        return std::string("<")
+            .append(std::to_string(self.getCoefficient()))
+            .append(", ")
+            .append(std::to_string(self.getExponent()))
+            .append(">");
+      });
+}
diff --git a/mlir/lib/CAPI/Dialect/CMakeLists.txt b/mlir/lib/CAPI/Dialect/CMakeLists.txt
index 4e141b60ff8cc..d2e330da33763 100644
--- a/mlir/lib/CAPI/Dialect/CMakeLists.txt
+++ b/mlir/lib/CAPI/Dialect/CMakeLists.txt
@@ -225,6 +225,16 @@ add_mlir_upstream_c_api_library(MLIRCAPIQuant
   MLIRQuantDialect
 )
 
+add_mlir_upstream_c_api_library(MLIRCAPIPolynomial
+  Polynomial.cpp
+
+  PARTIAL_SOURCES_INTENDED
+  LINK_LIBS PUBLIC
+  MLIRCAPIIR
+  MLIRPolynomialDialect
+)
+
+
 add_mlir_upstream_c_api_library(MLIRCAPIOpenMP
   OpenMP.cpp
 
diff --git a/mlir/lib/CAPI/Dialect/Polynomial.cpp b/mlir/lib/CAPI/Dialect/Polynomial.cpp
new file mode 100644
index 0000000000000..18e974c0a2efe
--- /dev/null
+++ b/mlir/lib/CAPI/Dialect/Polynomial.cpp
@@ -0,0 +1,32 @@
+//===- Polynomial.cpp - C Interface for Polynomial dialect ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir-c/Dialect/Polynomial.h"
+#include "mlir/CAPI/Registration.h"
+#include "mlir/Dialect/Polynomial/IR/PolynomialDialect.h"
+
+using namespace mlir;
+
+MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(polynomial, polynomial,
+                                      polynomial::PolynomialDialect)
+
+MlirIntMonomial mlirPolynomialGetIntMonomial(int64_t coeff, uint64_t expo) {
+  return wrap(new mlir::polynomial::IntMonomial(coeff, expo));
+}
+
+int64_t mlirPolynomialIntMonomialGetCoefficient(MlirIntMonomial intMonomial) {
+  return unwrap(intMonomial)
+      ->getCoefficient()
+      .getLimitedValue(/*Limit = UINT64_MAX*/);
+}
+
+uint64_t mlirPolynomialIntMonomialGetExponent(MlirIntMonomial intMonomial) {
+  return unwrap(intMonomial)
+      ->getExponent(/*Limit = UINT64_MAX*/)
+      .getLimitedValue();
+}
\ No newline at end of file
diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt
index d8f2d1989fdea..c3c3890e5debb 100644
--- a/mlir/python/CMakeLists.txt
+++ b/mlir/python/CMakeLists.txt
@@ -162,14 +162,22 @@ declare_mlir_dialect_python_bindings(
   GEN_ENUM_BINDINGS)
 
 declare_mlir_dialect_extension_python_bindings(
-ADD_TO_PARENT MLIRPythonSources.Dialects
-ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
+  ADD_TO_PARENT MLIRPythonSources.Dialects
+  ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
   TD_FILE dialects/TransformPDLExtensionOps.td
   SOURCES
     dialects/transform/pdl.py
   DIALECT_NAME transform
   EXTENSION_NAME transform_pdl_extension)
 
+declare_mlir_dialect_python_bindings(
+  ADD_TO_PARENT MLIRPythonSources.Dialects
+  ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
+  TD_FILE dialects/Polynomial.td
+  SOURCES
+    dialects/polynomial.py
+  DIALECT_NAME polynomial)
+
 declare_mlir_dialect_python_bindings(
   ADD_TO_PARENT MLIRPythonSources.Dialects
   ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
@@ -537,6 +545,19 @@ declare_mlir_python_extension(MLIRPythonExtension.Dialects.Quant.Pybind
     MLIRCAPIQuant
 )
 
+declare_mlir_python_extension(MLIRPythonExtension.Dialects.Polynomial.Pybind
+  MODULE_NAME _mlirDialectsPolynomial
+  ADD_TO_PARENT MLIRPythonSources.Dialects.polynomial
+  ROOT_DIR "${PYTHON_SOURCE_DIR}"
+  SOURCES
+    DialectPolynomial.cpp
+  PRIVATE_LINK_LIBS
+    LLVMSupport
+  EMBED_CAPI_LINK_LIBS
+    MLIRCAPIIR
+    MLIRCAPIPolynomial
+)
+
 declare_mlir_python_extension(MLIRPythonExtension.Dialects.NVGPU.Pybind
   MODULE_NAME _mlirDialectsNVGPU
   ADD_TO_PARENT MLIRPythonSources.Dialects.nvgpu
diff --git a/mlir/python/mlir/dialects/Polynomial.td b/mlir/python/mlir/dialects/Polynomial.td
new file mode 100644
index 0000000000000..b38cb05e47447
--- /dev/null
+++ b/mlir/python/mlir/dialects/Polynomial.td
@@ -0,0 +1,14 @@
+//===-- Polynomial.td - Entry point for Polynomial bind ---*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PYTHON_BINDINGS_POLYNOMIAL_OPS
+#define PYTHON_BINDINGS_POLYNOMIAL_OPS
+
+include "mlir/Dialect/Polynomial/IR/Polynomial.td"
+
+#endif
diff --git a/mlir/python/mlir/dialects/polynomial.py b/mlir/python/mlir/dialects/polynomial.py
new file mode 100644
index 0000000000000..5bd8084d5e5ef
--- /dev/null
+++ b/mlir/python/mlir/dialects/polynomial.py
@@ -0,0 +1,6 @@
+#  Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+#  See https://llvm.org/LICENSE.txt for license information.
+#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+from .._mlir_libs._mlirDialectsPolynomial import *
+from ._polynomial_ops_gen import *
diff --git a/mlir/test/python/dialects/polynomial.py b/mlir/test/python/dialects/polynomial.py
new file mode 100644
index 0000000000000..d7e308a6c2b54
--- /dev/null
+++ b/mlir/test/python/dialects/polynomial.py
@@ -0,0 +1,27 @@
+# RUN: %PYTHON %s | FileCheck %s
+
+from mlir.ir import *
+from mlir.dialects import polynomial
+
+
+def constructAndPrintInModule(f):
+    print("\nTEST:", f.__name__)
+    with Context(), Location.unknown():
+        module = Module.create()
+        with InsertionPoint(module.body):
+            f()
+        print(module)
+    return f
+
+
+# CHECK-LABEL: TEST: test_smoke
+@constructAndPrintInModule
+def test_smoke():
+    value = Attribute.parse("#polynomial.float_polynomial<0.5 + 1.3e06 x**2>")
+    res = polynomial.constant(value)
+    # CHECK: polynomial.constant float<0.5 + 1.3E+6x**2> : <ring = <coefficientType = f32>>
+    print(res)
+
+    int_poly = polynomial.IntMonomial(1, 10)
+    # CHECK: <1, 10>
+    print(int_poly)