diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py
index 62b3aec971..39efdea814 100644
--- a/commitizen/commands/init.py
+++ b/commitizen/commands/init.py
@@ -46,6 +46,10 @@ def is_python(self) -> bool:
     def is_rust_cargo(self) -> bool:
         return os.path.isfile("Cargo.toml")
 
+    @property
+    def is_maven_project(self) -> bool:
+        return os.path.isfile("pom.xml")
+
     @property
     def is_npm_package(self) -> bool:
         return os.path.isfile("package.json")
@@ -222,6 +226,7 @@ def _ask_version_provider(self) -> str:
             "commitizen": "commitizen: Fetch and set version in commitizen config (default)",
             "cargo": "cargo: Get and set version from Cargo.toml:project.version field",
             "composer": "composer: Get and set version from composer.json:project.version field",
+            "mvn": "mvn: Get and set version from pom.xml:project.version field",
             "npm": "npm: Get and set version from package.json:project.version field",
             "pep621": "pep621: Get and set version from pyproject.toml:project.version field",
             "poetry": "poetry: Get and set version from pyproject.toml:tool.poetry.version field",
@@ -236,6 +241,8 @@ def _ask_version_provider(self) -> str:
                 default_val = "pep621"
         elif self.project_info.is_rust_cargo:
             default_val = "cargo"
+        elif self.project_info.is_maven_project:
+            default_val = "mvn"
         elif self.project_info.is_npm_package:
             default_val = "npm"
         elif self.project_info.is_php_composer:
diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py
index 51302d2b37..5d992ee816 100644
--- a/commitizen/providers/__init__.py
+++ b/commitizen/providers/__init__.py
@@ -11,6 +11,7 @@
 from commitizen.providers.cargo_provider import CargoProvider
 from commitizen.providers.commitizen_provider import CommitizenProvider
 from commitizen.providers.composer_provider import ComposerProvider
+from commitizen.providers.mvn_provider import MavenProvider
 from commitizen.providers.npm_provider import NpmProvider
 from commitizen.providers.pep621_provider import Pep621Provider
 from commitizen.providers.poetry_provider import PoetryProvider
@@ -21,6 +22,7 @@
     "CargoProvider",
     "CommitizenProvider",
     "ComposerProvider",
+    "MavenProvider",
     "NpmProvider",
     "Pep621Provider",
     "PoetryProvider",
diff --git a/commitizen/providers/mvn_provider.py b/commitizen/providers/mvn_provider.py
new file mode 100644
index 0000000000..d7363914f6
--- /dev/null
+++ b/commitizen/providers/mvn_provider.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+
+import subprocess
+
+from commitizen.providers.base_provider import VersionProvider
+
+
+class MavenProvider(VersionProvider):
+    """
+    Maven version management
+
+    ref: https://octopus.com/blog/maven-versioning-explained
+
+    Major.Minor.Patch-BuildNumber-Qualifier
+
+    Precedence:
+     - alpha or a
+     - beta or b
+     - milestone or m
+     - rc or cr
+     - snapshot
+     - (the empty string) or ga or final or release
+     - sp
+    """
+
+    FULL_VERSION_REGEX = r"(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)[\.-]?(?P<buildnumber>\d+)?[\.-]?(?P<qualifier>\w+)?"
+
+    TAG_FORMAT_REGEXS = {
+        "$version": r"(?P<version>.+)",
+        "$major": r"(?P<major>\d+)",
+        "$minor": r"(?P<minor>\d+)",
+        "$patch": r"(?P<patch>\d+)",
+        "$buildnumber": r"(?P<buildnumber>\d+)?",
+        "$qualifier": r"(?P<qualifier>\w+)?",
+    }
+
+    filename = "./pom.xml"
+
+    def __run_cmd(self, cmd) -> str:
+        return (
+            subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+            .stdout.read()  # type: ignore
+            .decode("utf-8")
+            .strip()
+        )
+
+    def get_version(self, file: str = filename) -> str:
+        return self.__run_cmd(
+            f"mvn help:evaluate -Dexpression=project.version -q -DforceStdout -f {file}"
+        )
+
+    def set_version(self, version: str, file: str = filename) -> None:
+        self.__run_cmd(f"mvn versions:set -DnewVersion={version} -f {file}")
diff --git a/pyproject.toml b/pyproject.toml
index b644753b1b..251a957f5b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -93,6 +93,7 @@ restructuredtext = "commitizen.changelog_formats.restructuredtext:RestructuredTe
 cargo = "commitizen.providers:CargoProvider"
 commitizen = "commitizen.providers:CommitizenProvider"
 composer = "commitizen.providers:ComposerProvider"
+mvn = "commitizen.providers:MavenProvider"
 npm = "commitizen.providers:NpmProvider"
 pep621 = "commitizen.providers:Pep621Provider"
 poetry = "commitizen.providers:PoetryProvider"
diff --git a/tests/data/sample_pom.xml b/tests/data/sample_pom.xml
new file mode 100644
index 0000000000..50b9f372bd
--- /dev/null
+++ b/tests/data/sample_pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- PARENT -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>3.1.0</version>
+        <relativePath />
+    </parent>
+
+    <!-- BASICS -->
+    <groupId>io.github.commitizen-tools</groupId>
+    <artifactId>sample-maven-pom</artifactId>
+    <version>3.2.1</version>
+    <packaging>pom</packaging>
+
+    <!-- DESCRIPTION -->
+    <name>Sample Maven POM</name>
+    <description>This is a sample POM</description>
+
+    <scm>
+        <url>${app.url}</url>
+        <tag>v@{project.version}</tag>
+    </scm>
+
+    <!-- PROPS / VERSIONS -->
+    <properties>
+        <!-- App -->
+        <app.url>hthttps://github.com/commitizen-tools/commitizen</app.url>
+
+        <!-- Java -->
+        <java.version>17</java.version>
+
+        <!-- Spring -->
+        <spring-boot.version>3.1.0</spring-boot.version>
+    </properties>
+
+    <!-- BOM DEPS -->
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-devtools</artifactId>
+                <version>${spring-boot.version}</version>
+                <optional>true</optional>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-actuator</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-parent</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-web</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+</project>
diff --git a/tests/data/sample_pom_snapshot.xml b/tests/data/sample_pom_snapshot.xml
new file mode 100644
index 0000000000..694683b0fa
--- /dev/null
+++ b/tests/data/sample_pom_snapshot.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- PARENT -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>3.1.0</version>
+        <relativePath />
+    </parent>
+
+    <!-- BASICS -->
+    <groupId>io.github.commitizen-tools</groupId>
+    <artifactId>sample-maven-pom</artifactId>
+    <version>3.2.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <!-- DESCRIPTION -->
+    <name>Sample Maven POM</name>
+    <description>This is a sample POM</description>
+
+    <scm>
+        <url>${app.url}</url>
+        <tag>v@{project.version}</tag>
+    </scm>
+
+    <!-- PROPS / VERSIONS -->
+    <properties>
+        <!-- App -->
+        <app.url>hthttps://github.com/commitizen-tools/commitizen</app.url>
+
+        <!-- Java -->
+        <java.version>17</java.version>
+
+        <!-- Spring -->
+        <spring-boot.version>3.1.0</spring-boot.version>
+    </properties>
+
+    <!-- BOM DEPS -->
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-devtools</artifactId>
+                <version>${spring-boot.version}</version>
+                <optional>true</optional>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-actuator</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-parent</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-web</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+</project>
diff --git a/tests/providers/test_mvn_provider.py b/tests/providers/test_mvn_provider.py
new file mode 100644
index 0000000000..014831de6a
--- /dev/null
+++ b/tests/providers/test_mvn_provider.py
@@ -0,0 +1,50 @@
+from __future__ import annotations
+
+import pytest
+
+import os
+
+from commitizen.config.base_config import BaseConfig
+from commitizen.providers.mvn_provider import MavenProvider
+
+
+def test_can_run_subcommand(config: BaseConfig):
+    provider = MavenProvider(config)
+    got = provider._MavenProvider__run_cmd("echo 'hi'")  # type: ignore
+    expected = "hi"
+    assert got == expected
+
+
+@pytest.mark.parametrize(
+    "file, expected",
+    (
+        ("./tests/data/sample_pom.xml", "3.2.1"),
+        ("./tests/data/sample_pom_snapshot.xml", "3.2.1-SNAPSHOT"),
+    ),
+)
+def test_get_version(config: BaseConfig, file: str, expected: str):
+    provider = MavenProvider(config)
+    got = provider.get_version(file)
+    assert got == expected
+
+
+def test_set_version(config: BaseConfig):
+    provider = MavenProvider(config)
+    file = "./tests/data/sample_pom.xml"
+    expected = "3.2.2"
+    provider.set_version(expected, file)
+    got = provider.get_version(file)
+    assert got == expected
+
+    # rollback changes
+    expected = "3.2.1"
+    provider.set_version(expected, file)
+    got = provider.get_version(file)
+    assert got == expected
+
+    # delete backup file created
+    backup_file = file + ".versionsBackup"
+    assert os.path.exists(backup_file)
+    if os.path.exists(backup_file):
+        os.remove(backup_file)
+    assert not os.path.exists(backup_file)