diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..f92b2c20656c832253b695b6f5845a93465635b1
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h
@@ -0,0 +1,94 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbChangeInformationImageFilter_h
+#define __otbChangeInformationImageFilter_h
+
+#include "itkChangeInformationImageFilter.h"
+#include "otbMetaDataKey.h"
+
+namespace otb
+{
+
+/**
+ * \class ChangeInformationImageFilter
+ * \brief Filter to modify image metadata
+ *
+ * The base class is itk::ChangeInformationImageFilter that allows to
+ * modifiy origin, spacing, direction and buffered region. This deriving
+ * filter adds the support of MetaDataDictionary.
+ *
+ * \ingroup OTBImageManipulation
+ */
+template< typename TInputImage >
+class ChangeInformationImageFilter:
+  public itk::ChangeInformationImageFilter< TInputImage >
+{
+public:
+  /** Standard class typedefs. */
+  typedef ChangeInformationImageFilter                   Self;
+  typedef itk::ChangeInformationImageFilter<TInputImage> Superclass;
+  typedef itk::SmartPointer<Self>                        Pointer;
+  typedef itk::SmartPointer<const Self>                  ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Creation through object factory macro */
+  itkTypeMacro(ChangeInformationImageFilter, itk::ChangeInformationImageFilter);
+
+  /** Set key names to change */
+  void SetChangeMetaData(const char *keyname, bool flag);
+
+  /** Ask if a metadata will be changed */
+  bool GetChangeMetaData(const char *keyname);
+
+  /** Set output values for metadata, passing a NULL value will remove the
+   *  metadata from output. If not set for a key name in the change list,
+   *  the metadata will also be set.
+   */
+  template<typename T>
+  void SetOutputMetaData(const char *keyname, const T * value);
+
+protected:
+  ChangeInformationImageFilter() {}
+  virtual ~ChangeInformationImageFilter() {}
+
+  /** Apply changes to the output image metadata. */
+  virtual void GenerateOutputInformation();
+
+private:
+  ChangeInformationImageFilter(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+  /** Removes a field from a metadata dictionary
+   *  After ITK 4.6, an Erase() method has been added to
+   *  itk::MetaDataDictionary, so this function could be tagged as deprecated */
+  bool RemoveKeyFromDictionary(itk::MetaDataDictionary & dict, const std::string & key);
+
+  /** List of metadata keys to change */
+  std::set<std::string> m_ChangedKeys;
+
+};
+
+} // End of namespace OTB
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbChangeInformationImageFilter.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..319684064c4caf4a83c8be8b7fd460cae13d920d
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx
@@ -0,0 +1,150 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbChangeInformationImageFilter_txx
+#define __otbChangeInformationImageFilter_txx
+
+#include "otbChangeInformationImageFilter.h"
+#include "itkMetaDataObject.h"
+
+namespace otb
+{
+
+template< typename TInputImage >
+void
+ChangeInformationImageFilter<TInputImage>
+::SetChangeMetaData(const char *keyname, bool flag)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    if (flag)
+      {
+      m_ChangedKeys.insert(key);
+      }
+    else
+      {
+      std::set<std::string>::iterator pos = m_ChangedKeys.find(key);
+      if (pos != m_ChangedKeys.end())
+        {
+        m_ChangedKeys.erase(pos);
+        }
+      }
+    }
+}
+
+template< typename TInputImage >
+bool
+ChangeInformationImageFilter<TInputImage>
+::GetChangeMetaData(const char *keyname)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    if (m_ChangedKeys.find(key) != m_ChangedKeys.end())
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+template< typename TInputImage >
+template<typename T>
+void
+ChangeInformationImageFilter<TInputImage>
+::SetOutputMetaData(const char *keyname, const T * value)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    // enable this key for metadata change
+    m_ChangedKeys.insert(key);
+    itk::MetaDataDictionary &dict = this->GetMetaDataDictionary();
+    if (value == NULL)
+      {
+      // Remove meta-data from dictionary
+      this->RemoveKeyFromDictionary(dict,key);
+      }
+    else
+      {
+      // Set metadata in dictionary
+      const T &valueRef = (*value);
+      itk::EncapsulateMetaData<T>(dict,key,valueRef);
+      }
+    }
+}
+
+template< typename TInputImage >
+void
+ChangeInformationImageFilter<TInputImage>
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+
+  // Process the metadatas to be changed
+  itk::MetaDataDictionary &dict = this->GetMetaDataDictionary();
+  itk::MetaDataDictionary &outputDict = this->GetOutput()->GetMetaDataDictionary();
+  std::set<std::string>::iterator it = m_ChangedKeys.begin();
+  for ( ; it != m_ChangedKeys.end() ; ++it)
+    {
+    if (dict.HasKey(*it))
+      {
+      // Replace metadata in output dictionary
+      outputDict[*it] = dict[*it];
+      }
+    else
+      {
+      // Remove metadata from output dictionary
+      this->RemoveKeyFromDictionary(outputDict,*it);
+      }
+    }
+}
+
+template< typename TInputImage >
+bool
+ChangeInformationImageFilter<TInputImage>
+::RemoveKeyFromDictionary(itk::MetaDataDictionary & dict, const std::string & key)
+{
+  std::vector<std::string> keyList = dict.GetKeys();
+  std::vector<std::string>::iterator pos = keyList.begin();
+  while (pos != keyList.end())
+    {
+    if (key.compare(*pos) == 0)
+      {
+      break;
+      }
+    ++pos;
+    }
+  if (pos != keyList.end())
+    {
+    itk::MetaDataDictionary copyDict;
+    keyList.erase(pos);
+    pos = keyList.begin();
+    for ( ; pos != keyList.end();++pos)
+      {
+      copyDict.Set(*pos, const_cast<itk::MetaDataObjectBase*>(dict.Get(*pos)));
+      }
+    dict = copyDict;
+    return true;
+    }
+  return false;
+}
+
+} // End of namespace OTB
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
index 86e9cd72c67dca156fc4fd293c9b220ff186fc21..3019412f1434a6242298ef6d9fc9eff55aa520d2 100644
--- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
@@ -75,6 +75,7 @@ otbOneRIBandImageToOneComplexBandImage.cxx
 otbTwoNRIBandsImageToNComplexBandsImage.cxx
 otbChangeNoDataValueFilter.cxx
 otbImageToNoDataMaskFilter.cxx
+otbChangeInformationImageFilter.cxx
 )
 
 add_executable(otbImageManipulationTestDriver ${OTBImageManipulationTests})
@@ -710,3 +711,8 @@ otb_add_test(NAME filteringImageManipulationChangeNoDataValueFilter COMMAND otbI
 
 otb_add_test(NAME filteringImageManipulationImageToNoDataMaskFilter COMMAND otbImageManipulationTestDriver
   otbImageToNoDataMaskFilter)
+
+otb_add_test(NAME bfTvChangeInformationImageFilter COMMAND  otbImageManipulationTestDriver
+  otbChangeInformationImageFilter
+  ${INPUTDATA}/WV2_PAN_ROI_1000_100.tif
+  )
diff --git a/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2a6a7e2a904cee67cfa8d15e7bf7d3be65126ece
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx
@@ -0,0 +1,66 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "otbChangeInformationImageFilter.h"
+#include "otbImageFileReader.h"
+#include "otbImage.h"
+
+int otbChangeInformationImageFilter(int itkNotUsed(argc), char * argv[])
+{
+  const char *inputFilename(argv[1]);
+
+  typedef otb::Image<float,2> ImageType;
+  typedef otb::ChangeInformationImageFilter<ImageType> FilterType;
+  typedef otb::ImageFileReader<ImageType> ReaderType;
+  
+  ReaderType::Pointer reader = ReaderType::New();
+  reader->SetFileName(inputFilename);
+  
+  FilterType::Pointer filter = FilterType::New();
+  filter->SetInput(reader->GetOutput());
+  // try to set a different ProjRef
+  std::string newProj("Fake ProjRef");
+  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey,&newProj);
+  // erase that choice
+  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey,NULL);
+  // add a no data to the image
+  std::vector<bool> flags;
+  flags.push_back(true);
+  std::vector<double> nodata;
+  nodata.push_back(0.0);
+  filter->SetOutputMetaData<std::vector<bool> >(otb::MetaDataKey::NoDataValueAvailable,&flags);
+  filter->SetOutputMetaData<std::vector<double> >(otb::MetaDataKey::NoDataValue,&nodata);
+  filter->UpdateOutputInformation();
+
+  ImageType::Pointer outImage = filter->GetOutput();
+  if (! outImage->GetProjectionRef().empty())
+    {
+    std::cout << "Projection is supposed to be removed but is still present !" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  itk::MetaDataDictionary &dict = outImage->GetMetaDataDictionary();
+  if (!dict.HasKey(otb::MetaDataKey::NoDataValueAvailable) ||
+      !dict.HasKey(otb::MetaDataKey::NoDataValue))
+    {
+    std::cout << "Missing no data metadata !" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
+
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
index f732d0d2a493a927ccfd34f1f5633d85b3508cf3..299f6744511b2d781a1f5a0d973b4c122c44674b 100644
--- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
@@ -81,4 +81,5 @@ void RegisterTests()
   REGISTER_TEST(otbTwoNRIBandsImageToNComplexBandsImage);
   REGISTER_TEST(otbChangeNoDataValueFilter);
   REGISTER_TEST(otbImageToNoDataMaskFilter);
+  REGISTER_TEST(otbChangeInformationImageFilter);
 }