diff --git a/autotest/gcore/cog.py b/autotest/gcore/cog.py
index 36487c71f86b..b6b95c0d78cc 100755
--- a/autotest/gcore/cog.py
+++ b/autotest/gcore/cog.py
@@ -1560,3 +1560,24 @@ def test_cog_copy_mdd():
ds = None
gdal.Unlink(filename)
+
+
+###############################################################################
+# Test NBITS creation option
+
+
+def test_cog_NBITS():
+
+ src_ds = gdal.GetDriverByName("MEM").Create("", 1, 1)
+ drv = gdal.GetDriverByName("COG")
+ filename = "/vsimem/test_cog_NBITS.tif"
+ drv.CreateCopy(
+ filename,
+ src_ds,
+ options=["NBITS=7"],
+ )
+ ds = gdal.Open(filename)
+ assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "7"
+ ds = None
+
+ gdal.Unlink(filename)
diff --git a/doc/source/drivers/raster/cog.rst b/doc/source/drivers/raster/cog.rst
index aaa9dff0bb5f..3d8215aa0cf3 100644
--- a/doc/source/drivers/raster/cog.rst
+++ b/doc/source/drivers/raster/cog.rst
@@ -83,6 +83,12 @@ General creation options
or TARGET_SRS creation options. (Overview generation is also multithreaded since
GDAL 3.2)
+- **NBITS=n**: (GDAL >= 3.7) Create a file with less than 8 bits per sample by
+ passing a value from 1 to 7. The apparent pixel type should be Byte.
+ Values of n=9...15 (UInt16 type) and n=17...31
+ (UInt32 type) are also accepted. From GDAL 2.2, n=16 is accepted for
+ Float32 type to generate half-precision floating point values.
+
- **PREDICTOR=[YES/NO/STANDARD/FLOATING_POINT]**: Set the predictor for LZW,
DEFLATE and ZSTD compression. The default is NO. If YES is specified, then
standard predictor (Predictor=2) is used for integer data type,
diff --git a/frmts/gtiff/cogdriver.cpp b/frmts/gtiff/cogdriver.cpp
index d3be1a9a0e66..8818863cfc96 100644
--- a/frmts/gtiff/cogdriver.cpp
+++ b/frmts/gtiff/cogdriver.cpp
@@ -1091,6 +1091,7 @@ GDALDataset *GDALCOGCreator::Create(const char *pszFilename,
CSLFetchNameValue(papszOptions, "GEOTIFF_VERSION"));
aosOptions.SetNameValue("SPARSE_OK",
CSLFetchNameValue(papszOptions, "SPARSE_OK"));
+ aosOptions.SetNameValue("NBITS", CSLFetchNameValue(papszOptions, "NBITS"));
if (EQUAL(osOverviews, "NONE"))
{
@@ -1315,6 +1316,9 @@ void GDALCOGDriver::InitializeCreationOptionList()
" "
+ " "
" "
"